Commit c2214519 authored by Ray Strode's avatar Ray Strode

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
parents 77c791af 5e737a57
......@@ -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;
......
......@@ -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 */
......@@ -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);
......
......@@ -294,37 +294,6 @@ is_login_session (GdmManager *self,
return TRUE;
}
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment