summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <halfline@gmail.com>2018-08-02 20:07:18 +0000
committerRay Strode <halfline@gmail.com>2018-08-02 20:07:18 +0000
commitc22145194b7153253743c94d95c7e1f1a056b7d3 (patch)
treef57c7b738d025aef9ac83908fd0d927478fbe438
parent77c791afa4dc02ef7c6f3278dd20b23d69cee7fe (diff)
parent5e737a57402fa626af7f037b9485bd172c8a3dff (diff)
downloadgdm-c22145194b7153253743c94d95c7e1f1a056b7d3.tar.gz
Merge branch 'wip/try-harder-to-get-a-login-screen' into 'master'
Wip/try harder to get a login screen See merge request GNOME/gdm!25
-rw-r--r--common/gdm-common.c57
-rw-r--r--common/gdm-common.h8
-rw-r--r--daemon/gdm-local-display-factory.c36
-rw-r--r--daemon/gdm-manager.c178
4 files changed, 80 insertions, 199 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c
index a5b59242..d807c019 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -352,10 +352,10 @@ create_transient_display (GDBusConnection *connection,
return TRUE;
}
-static gboolean
-activate_session_id (GDBusConnection *connection,
- const char *seat_id,
- const char *session_id)
+gboolean
+gdm_activate_session_by_id (GDBusConnection *connection,
+ const char *seat_id,
+ const char *session_id)
{
GError *local_error = NULL;
GVariant *reply;
@@ -381,13 +381,14 @@ activate_session_id (GDBusConnection *connection,
return TRUE;
}
-static gboolean
-get_login_window_session_id (const char *seat_id,
- char **session_id)
+gboolean
+gdm_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;
@@ -399,13 +400,19 @@ get_login_window_session_id (const char *seat_id,
if (sessions == NULL || sessions[0] == NULL) {
*session_id = NULL;
- ret = TRUE;
+ ret = FALSE;
goto out;
}
for (i = 0; sessions[i]; i ++) {
+
res = sd_session_get_class (sessions[i], &service_class);
if (res < 0) {
+ if (res == -ENOENT) {
+ free (service_class);
+ continue;
+ }
+
g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res));
ret = FALSE;
goto out;
@@ -431,21 +438,35 @@ get_login_window_session_id (const char *seat_id,
}
free (state);
- *session_id = g_strdup (sessions[i]);
- ret = TRUE;
- break;
+ 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;
+ ret = FALSE;
out:
- for (i = 0; sessions[i]; i ++) {
- free (sessions[i]);
- }
+ if (sessions) {
+ for (i = 0; sessions[i]; i ++) {
+ free (sessions[i]);
+ }
- free (sessions);
+ free (sessions);
+ }
return ret;
}
@@ -506,9 +527,9 @@ goto_login_session (GDBusConnection *connection,
return FALSE;
}
- res = get_login_window_session_id (seat_id, &session_id);
+ res = gdm_get_login_window_session_id (seat_id, &session_id);
if (res && session_id != NULL) {
- res = activate_session_id (connection, seat_id, session_id);
+ res = gdm_activate_session_by_id (connection, seat_id, session_id);
if (res) {
ret = TRUE;
diff --git a/common/gdm-common.h b/common/gdm-common.h
index e13c3a3d..07812b10 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -22,6 +22,8 @@
#define _GDM_COMMON_H
#include <glib-unix.h>
+#include <gio/gio.h>
+
#include <pwd.h>
#include <errno.h>
@@ -51,6 +53,8 @@ gboolean gdm_clear_close_on_exec_flag (int fd);
char *gdm_generate_random_bytes (gsize size,
GError **error);
+gboolean gdm_get_login_window_session_id (const char *seat_id,
+ char **session_id);
gboolean gdm_goto_login_session (GError **error);
GPtrArray *gdm_get_script_environment (const char *username,
@@ -69,6 +73,10 @@ char * gdm_shell_expand (const char *str,
GdmExpandVarFunc expand_func,
gpointer user_data);
+gboolean gdm_activate_session_by_id (GDBusConnection *connection,
+ const char *seat_id,
+ const char *session_id);
+
G_END_DECLS
#endif /* _GDM_COMMON_H */
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index f68eda8d..f214185f 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -28,6 +28,8 @@
#include <glib-object.h>
#include <gio/gio.h>
+#include <systemd/sd-login.h>
+
#include "gdm-common.h"
#include "gdm-manager.h"
#include "gdm-display-factory.h"
@@ -267,6 +269,7 @@ on_display_status_changed (GdmDisplay *display,
int num;
char *seat_id = NULL;
char *session_type = NULL;
+ char *session_class = NULL;
gboolean is_initial = TRUE;
gboolean is_local = TRUE;
@@ -278,6 +281,7 @@ on_display_status_changed (GdmDisplay *display,
"is-initial", &is_initial,
"is-local", &is_local,
"session-type", &session_type,
+ "session-class", &session_class,
NULL);
status = gdm_display_get_status (display);
@@ -297,7 +301,7 @@ on_display_status_changed (GdmDisplay *display,
* ensures we get a new login screen when the user logs out,
* if there isn't one.
*/
- if (is_local) {
+ if (is_local && g_strcmp0 (session_class, "greeter") != 0) {
/* reset num failures */
factory->priv->num_failures = 0;
@@ -342,6 +346,7 @@ on_display_status_changed (GdmDisplay *display,
g_free (seat_id);
g_free (session_type);
+ g_free (session_class);
}
static gboolean
@@ -370,12 +375,33 @@ create_display (GdmLocalDisplayFactory *factory,
{
GdmDisplayStore *store;
GdmDisplay *display = NULL;
+ char *active_session_id = NULL;
+ int ret;
- /* Ensure we don't create the same display more than once */
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
- display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
- if (display != NULL) {
- return NULL;
+
+ ret = sd_seat_get_active (seat_id, &active_session_id, NULL);
+
+ if (ret == 0) {
+ char *login_session_id = NULL;
+
+ /* If we already have a login window, switch to it */
+ if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
+ if (g_strcmp0 (active_session_id, login_session_id) != 0) {
+ gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id);
+ }
+ g_clear_pointer (&login_session_id, g_free);
+ g_clear_pointer (&active_session_id, g_free);
+ return NULL;
+ }
+ g_clear_pointer (&active_session_id, g_free);
+ } else {
+ /* Ensure we don't create the same display more than once */
+ display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
+
+ if (display != NULL) {
+ return NULL;
+ }
}
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 1370bab4..f17bd1a5 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -295,37 +295,6 @@ is_login_session (GdmManager *self,
}
static gboolean
-activate_session_id (GdmManager *manager,
- const char *seat_id,
- const char *session_id)
-{
- GError *error = NULL;
- GVariant *reply;
-
- reply = g_dbus_connection_call_sync (manager->priv->connection,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "ActivateSessionOnSeat",
- g_variant_new ("(ss)", session_id, seat_id),
- NULL, /* expected reply */
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (reply == NULL) {
- g_debug ("GdmManager: logind 'ActivateSessionOnSeat' %s raised:\n %s\n\n",
- g_dbus_error_get_remote_error (error), error->message);
- g_error_free (error);
- return FALSE;
- }
-
- g_variant_unref (reply);
-
- return TRUE;
-}
-
-static gboolean
session_unlock (GdmManager *manager,
const char *ssid)
{
@@ -621,7 +590,7 @@ switch_to_compatible_user_session (GdmManager *manager,
if (existing_session != NULL) {
ssid_to_activate = gdm_session_get_session_id (existing_session);
if (seat_id != NULL) {
- res = activate_session_id (manager, seat_id, ssid_to_activate);
+ res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate);
if (! res) {
g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
goto out;
@@ -1318,148 +1287,6 @@ 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) {
- if (res == -ENOENT) {
- free (service_class);
- continue;
- }
-
- 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) {
- if (res == -ENOENT)
- continue;
-
- 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) {
- if (res == -ENOENT)
- continue;
- 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;
- }
-
- if (session_id) {
- activate_session_id (self, seat_id, session_id);
- g_free (session_id);
- }
-}
-
-static void
-maybe_activate_other_session (GdmManager *self,
- GdmDisplay *old_display)
-{
- char *seat_id = NULL;
- char *session_id = NULL;
- 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 || gdm_display_get_status (display) == GDM_DISPLAY_FINISHED) {
- activate_login_window_session_on_seat (self, seat_id);
- }
-
- g_free (session_id);
- }
-
- g_free (seat_id);
-}
-
static const char *
get_username_for_greeter_display (GdmManager *manager,
GdmDisplay *display)
@@ -1705,7 +1532,6 @@ on_display_status_changed (GdmDisplay *display,
manager->priv->ran_once = TRUE;
}
maybe_start_pending_initial_login (manager, display);
- maybe_activate_other_session (manager, display);
break;
default:
break;
@@ -2059,7 +1885,7 @@ on_session_reauthenticated (GdmSession *session,
char *session_id;
seat_id = gdm_session_get_display_seat_id (session);
- if (get_login_window_session_id (seat_id, &session_id)) {
+ if (gdm_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);