From 2724b4fd6d4ac527acc481f056f535141b63fe24 Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Tue, 7 May 2019 15:57:43 +0100 Subject: [PATCH 49/51] GdmManager, GdmDisplay: Add RegisterSession method Window managers can use this to register with GDM when they've finished starting up and started displaying. --- daemon/gdm-display.c | 24 ++++++++++++++++++++++++ daemon/gdm-manager.c | 30 ++++++++++++++++++++++++++++++ daemon/gdm-manager.xml | 3 +++ 3 files changed, 57 insertions(+) diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index 1cef8c7c1..56799741d 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -64,82 +64,84 @@ struct GdmDisplayPrivate char *remote_hostname; int x11_display_number; char *x11_display_name; int status; time_t creation_time; GTimer *server_timer; char *x11_cookie; gsize x11_cookie_size; GdmDisplayAccessFile *access_file; guint finish_idle_id; xcb_connection_t *xcb_connection; int xcb_screen_number; GDBusConnection *connection; GdmDisplayAccessFile *user_access_file; GdmDBusDisplay *display_skeleton; GDBusObjectSkeleton *object_skeleton; /* this spawns and controls the greeter session */ GdmLaunchEnvironment *launch_environment; guint is_local : 1; guint is_initial : 1; guint allow_timed_login : 1; guint have_existing_user_accounts : 1; guint doing_initial_setup : 1; + guint session_registered : 1; }; enum { PROP_0, PROP_ID, PROP_STATUS, PROP_SEAT_ID, PROP_SESSION_ID, PROP_SESSION_CLASS, PROP_SESSION_TYPE, PROP_REMOTE_HOSTNAME, PROP_X11_DISPLAY_NUMBER, PROP_X11_DISPLAY_NAME, PROP_X11_COOKIE, PROP_X11_AUTHORITY_FILE, PROP_IS_CONNECTED, PROP_IS_LOCAL, PROP_LAUNCH_ENVIRONMENT, PROP_IS_INITIAL, PROP_ALLOW_TIMED_LOGIN, PROP_HAVE_EXISTING_USER_ACCOUNTS, PROP_DOING_INITIAL_SETUP, + PROP_SESSION_REGISTERED, }; static void gdm_display_class_init (GdmDisplayClass *klass); static void gdm_display_init (GdmDisplay *self); static void gdm_display_finalize (GObject *object); static void queue_finish (GdmDisplay *self); static void _gdm_display_set_status (GdmDisplay *self, int status); static gboolean wants_initial_setup (GdmDisplay *self); G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT) GQuark gdm_display_error_quark (void) { static GQuark ret = 0; if (ret == 0) { ret = g_quark_from_static_string ("gdm_display_error"); } return ret; } time_t gdm_display_get_creation_time (GdmDisplay *self) { g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); return self->priv->creation_time; } @@ -733,60 +735,68 @@ static void _gdm_display_set_x11_display_number (GdmDisplay *self, int num) { self->priv->x11_display_number = num; } static void _gdm_display_set_x11_display_name (GdmDisplay *self, const char *x11_display) { g_free (self->priv->x11_display_name); self->priv->x11_display_name = g_strdup (x11_display); } static void _gdm_display_set_x11_cookie (GdmDisplay *self, const char *x11_cookie) { g_free (self->priv->x11_cookie); self->priv->x11_cookie = g_strdup (x11_cookie); } static void _gdm_display_set_is_local (GdmDisplay *self, gboolean is_local) { g_debug ("GdmDisplay: local: %s", is_local? "yes" : "no"); self->priv->is_local = is_local; } +static void +_gdm_display_set_session_registered (GdmDisplay *self, + gboolean registered) +{ + g_debug ("GdmDisplay: session registered: %s", registered? "yes" : "no"); + self->priv->session_registered = registered; +} + static void _gdm_display_set_launch_environment (GdmDisplay *self, GdmLaunchEnvironment *launch_environment) { g_clear_object (&self->priv->launch_environment); self->priv->launch_environment = g_object_ref (launch_environment); } static void _gdm_display_set_is_initial (GdmDisplay *self, gboolean initial) { g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no"); self->priv->is_initial = initial; } static void _gdm_display_set_allow_timed_login (GdmDisplay *self, gboolean allow_timed_login) { g_debug ("GdmDisplay: allow timed login: %s", allow_timed_login? "yes" : "no"); self->priv->allow_timed_login = allow_timed_login; } static void gdm_display_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -811,60 +821,63 @@ gdm_display_set_property (GObject *object, case PROP_SESSION_CLASS: _gdm_display_set_session_class (self, g_value_get_string (value)); break; case PROP_SESSION_TYPE: _gdm_display_set_session_type (self, g_value_get_string (value)); break; case PROP_REMOTE_HOSTNAME: _gdm_display_set_remote_hostname (self, g_value_get_string (value)); break; case PROP_X11_DISPLAY_NUMBER: _gdm_display_set_x11_display_number (self, g_value_get_int (value)); break; case PROP_X11_DISPLAY_NAME: _gdm_display_set_x11_display_name (self, g_value_get_string (value)); break; case PROP_X11_COOKIE: _gdm_display_set_x11_cookie (self, g_value_get_string (value)); break; case PROP_IS_LOCAL: _gdm_display_set_is_local (self, g_value_get_boolean (value)); break; case PROP_ALLOW_TIMED_LOGIN: _gdm_display_set_allow_timed_login (self, g_value_get_boolean (value)); break; case PROP_LAUNCH_ENVIRONMENT: _gdm_display_set_launch_environment (self, g_value_get_object (value)); break; case PROP_IS_INITIAL: _gdm_display_set_is_initial (self, g_value_get_boolean (value)); break; + case PROP_SESSION_REGISTERED: + _gdm_display_set_session_registered (self, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gdm_display_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GdmDisplay *self; self = GDM_DISPLAY (object); switch (prop_id) { case PROP_ID: g_value_set_string (value, self->priv->id); break; case PROP_STATUS: g_value_set_int (value, self->priv->status); break; case PROP_SEAT_ID: g_value_set_string (value, self->priv->seat_id); break; case PROP_SESSION_ID: g_value_set_string (value, self->priv->session_id); break; case PROP_SESSION_CLASS: @@ -881,60 +894,63 @@ gdm_display_get_property (GObject *object, break; case PROP_X11_DISPLAY_NAME: g_value_set_string (value, self->priv->x11_display_name); break; case PROP_X11_COOKIE: g_value_set_string (value, self->priv->x11_cookie); break; case PROP_X11_AUTHORITY_FILE: g_value_take_string (value, self->priv->access_file? gdm_display_access_file_get_path (self->priv->access_file) : NULL); break; case PROP_IS_LOCAL: g_value_set_boolean (value, self->priv->is_local); break; case PROP_IS_CONNECTED: g_value_set_boolean (value, self->priv->xcb_connection != NULL); break; case PROP_LAUNCH_ENVIRONMENT: g_value_set_object (value, self->priv->launch_environment); break; case PROP_IS_INITIAL: g_value_set_boolean (value, self->priv->is_initial); break; case PROP_HAVE_EXISTING_USER_ACCOUNTS: g_value_set_boolean (value, self->priv->have_existing_user_accounts); break; case PROP_DOING_INITIAL_SETUP: g_value_set_boolean (value, self->priv->doing_initial_setup); break; + case PROP_SESSION_REGISTERED: + g_value_set_boolean (value, priv->session_registered); + break; case PROP_ALLOW_TIMED_LOGIN: g_value_set_boolean (value, self->priv->allow_timed_login); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static gboolean handle_get_id (GdmDBusDisplay *skeleton, GDBusMethodInvocation *invocation, GdmDisplay *self) { char *id; gdm_display_get_id (self, &id, NULL); gdm_dbus_display_complete_get_id (skeleton, invocation, id); g_free (id); return TRUE; } static gboolean handle_get_remote_hostname (GdmDBusDisplay *skeleton, GDBusMethodInvocation *invocation, GdmDisplay *self) { char *hostname; @@ -1197,60 +1213,68 @@ gdm_display_class_init (GdmDisplayClass *klass) G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_IS_LOCAL, g_param_spec_boolean ("is-local", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_IS_CONNECTED, g_param_spec_boolean ("is-connected", NULL, NULL, TRUE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_HAVE_EXISTING_USER_ACCOUNTS, g_param_spec_boolean ("have-existing-user-accounts", NULL, NULL, FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_DOING_INITIAL_SETUP, g_param_spec_boolean ("doing-initial-setup", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_SESSION_REGISTERED, + g_param_spec_boolean ("session-registered", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_LAUNCH_ENVIRONMENT, g_param_spec_object ("launch-environment", NULL, NULL, GDM_TYPE_LAUNCH_ENVIRONMENT, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_STATUS, g_param_spec_int ("status", "status", "status", -1, G_MAXINT, GDM_DISPLAY_UNMANAGED, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_type_class_add_private (klass, sizeof (GdmDisplayPrivate)); } static void gdm_display_init (GdmDisplay *self) { self->priv = GDM_DISPLAY_GET_PRIVATE (self); self->priv->creation_time = time (NULL); self->priv->server_timer = g_timer_new (); } diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index b147d73db..bff602a07 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -789,60 +789,89 @@ gdm_manager_handle_register_display (GdmDBusManager *manager, if (session != NULL) { GPid pid; if (x11_display_name != NULL) { g_object_set (G_OBJECT (session), "display-name", x11_display_name, NULL); g_object_set (G_OBJECT (display), "x11-display-name", x11_display_name, NULL); } /* 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_register_session (GdmDBusManager *manager, + GDBusMethodInvocation *invocation, + GVariant *details) +{ + GdmManager *self = GDM_MANAGER (manager); + GdmDisplay *display; + const char *sender; + GDBusConnection *connection; + + 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, NULL, NULL, NULL, NULL); + + g_debug ("GdmManager: trying to register new session on display %p", display); + + if (display != NULL) + g_object_set (G_OBJECT (display), "session-registered", TRUE, NULL); + else + g_debug ("GdmManager: No display, not registering"); + + gdm_dbus_manager_complete_register_session (GDM_DBUS_MANAGER (manager), + invocation); + + 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 = 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; } #ifdef HAVE_LIBXDMCP @@ -1167,60 +1196,61 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager g_hash_table_insert (self->priv->open_reauthentication_requests, GINT_TO_POINTER (pid), invocation); } else if (is_login_screen) { g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED, "Login screen only allowed to open reauthentication channels for running sessions"); return TRUE; } else { char *address; address = open_temporary_reauthentication_channel (self, seat_id, session_id, pid, uid, is_remote); gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), invocation, address); g_free (address); } return TRUE; } static void manager_interface_init (GdmDBusManagerIface *interface) { interface->handle_register_display = gdm_manager_handle_register_display; + interface->handle_register_session = gdm_manager_handle_register_session; interface->handle_open_session = gdm_manager_handle_open_session; interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel; } static gboolean display_is_on_seat0 (GdmDisplay *display) { gboolean is_on_seat0 = TRUE; char *seat_id = NULL; g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL); if (g_strcmp0 (seat_id, "seat0") != 0) { is_on_seat0 = FALSE; } g_free (seat_id); return is_on_seat0; } static gboolean get_timed_login_details (GdmManager *manager, char **usernamep, int *delayp) { gboolean res; gboolean enabled; int delay; diff --git a/daemon/gdm-manager.xml b/daemon/gdm-manager.xml index f11f3fb73..92ef1d02d 100644 --- a/daemon/gdm-manager.xml +++ b/daemon/gdm-manager.xml @@ -1,16 +1,19 @@ + + + -- 2.28.0