diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2014-02-25 12:32:21 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2014-03-17 16:32:17 -0400 |
commit | d7aa7246d7c6d2bc13bc513c29f3e7ce2a0ff2cc (patch) | |
tree | 31769ab3e3466df6feb558b1a90963d7b3c5779e /daemon | |
parent | 236102c0e17a1b13328dd86f60cc0495ebd3d03b (diff) | |
download | gdm-d7aa7246d7c6d2bc13bc513c29f3e7ce2a0ff2cc.tar.gz |
Integrate the slaves into the main daemon process
For no particular reason, the slave has been kept as a separate process.
Integrate this into the main display process by simply making the display
keep a handle to a GdmSlave object. To keep the cleanup simple, we won't
remove the GdmSlave subtypes yet. A future cleanup should merge the slave
functionality into GdmDisplay and its subtypes.
https://bugzilla.gnome.org/show_bug.cgi?id=726380
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Makefile.am | 154 | ||||
-rw-r--r-- | daemon/gdm-display.c | 385 | ||||
-rw-r--r-- | daemon/gdm-display.h | 21 | ||||
-rw-r--r-- | daemon/gdm-display.xml | 6 | ||||
-rw-r--r-- | daemon/gdm-manager.c | 1079 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.c | 867 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.h | 1 | ||||
-rw-r--r-- | daemon/gdm-slave-job.c | 478 | ||||
-rw-r--r-- | daemon/gdm-slave-job.h | 65 | ||||
-rw-r--r-- | daemon/gdm-slave.c | 983 | ||||
-rw-r--r-- | daemon/gdm-slave.h | 37 | ||||
-rw-r--r-- | daemon/gdm-slave.xml | 19 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-display.c | 91 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-display.h | 1 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-slave.c | 84 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-slave.h | 1 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-slave.xml | 8 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-display-factory.c | 18 | ||||
-rw-r--r-- | daemon/simple-slave-main.c | 191 | ||||
-rw-r--r-- | daemon/xdmcp-chooser-slave-main.c | 188 |
20 files changed, 1349 insertions, 3328 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 87fcb988..85425aa9 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -33,8 +33,6 @@ AM_CPPFLAGS = \ $(NULL) BUILT_SOURCES = \ - gdm-slave-glue.h \ - gdm-xdmcp-chooser-slave-glue.h \ gdm-display-glue.h \ gdm-manager-glue.h \ gdm-static-display-glue.h \ @@ -100,20 +98,6 @@ gdm-session-worker-glue.c gdm-session-worker-glue.h : gdm-session-worker.xml Mak --generate-c-code=gdm-session-worker-glue \ $(srcdir)/gdm-session-worker.xml -gdm-slave-glue.c gdm-slave-glue.h: gdm-slave.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-slave-glue \ - $(srcdir)/gdm-slave.xml - -gdm-xdmcp-chooser-slave-glue.c gdm-xdmcp-chooser-slave-glue.h: gdm-xdmcp-chooser-slave.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-xdmcp-chooser-slave-glue \ - $(srcdir)/gdm-xdmcp-chooser-slave.xml - noinst_PROGRAMS = \ test-session-client \ $(NULL) @@ -134,109 +118,9 @@ test_session_client_LDADD = \ $(NULL) libexec_PROGRAMS = \ - gdm-simple-slave \ gdm-session-worker \ $(NULL) -if XDMCP_SUPPORT -libexec_PROGRAMS += \ - gdm-xdmcp-chooser-slave \ - $(NULL) -endif - -gdm_simple_slave_SOURCES = \ - simple-slave-main.c \ - gdm-launch-environment.c \ - gdm-launch-environment.h \ - gdm-server.c \ - gdm-server.h \ - gdm-session.c \ - gdm-session.h \ - gdm-session-record.c \ - gdm-session-record.h \ - gdm-session-worker-common.c \ - gdm-session-worker-common.h \ - gdm-session-worker-job.c \ - gdm-session-worker-job.h \ - gdm-xerrors.h \ - gdm-xerrors.c \ - gdm-slave.c \ - gdm-slave.h \ - gdm-simple-slave.c \ - gdm-simple-slave.h \ - gdm-dbus-util.c \ - gdm-dbus-util.h \ - $(NULL) - -nodist_gdm_simple_slave_SOURCES = \ - gdm-display-glue.c \ - gdm-display-glue.h \ - gdm-session-enum-types.c \ - gdm-session-enum-types.h \ - gdm-session-glue.c \ - gdm-session-glue.h \ - gdm-session-worker-glue.c \ - gdm-session-worker-glue.h \ - gdm-slave-glue.c \ - gdm-slave-glue.h \ - $(NULL) - -gdm_simple_slave_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(XLIB_LIBS) \ - $(DAEMON_LIBS) \ - $(EXTRA_DAEMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(JOURNALD_LIBS) \ - $(PAM_LIBS) \ - $(NULL) - -gdm_xdmcp_chooser_slave_SOURCES = \ - xdmcp-chooser-slave-main.c \ - gdm-session.c \ - gdm-session.h \ - gdm-session-record.c \ - gdm-session-record.h \ - gdm-session-worker-common.c \ - gdm-session-worker-common.h \ - gdm-session-worker-job.c \ - gdm-session-worker-job.h \ - gdm-launch-environment.c \ - gdm-launch-environment.h \ - gdm-xerrors.h \ - gdm-xerrors.c \ - gdm-slave.c \ - gdm-slave.h \ - gdm-xdmcp-chooser-slave.c \ - gdm-xdmcp-chooser-slave.h \ - gdm-dbus-util.c \ - gdm-dbus-util.h \ - $(NULL) - -nodist_gdm_xdmcp_chooser_slave_SOURCES = \ - gdm-session-glue.c \ - gdm-session-glue.h \ - gdm-session-worker-glue.c \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.c \ - gdm-session-enum-types.h \ - gdm-display-glue.c \ - gdm-display-glue.h \ - gdm-slave-glue.c \ - gdm-slave-glue.h \ - gdm-xdmcp-chooser-slave-glue.c \ - gdm-xdmcp-chooser-slave-glue.h \ - $(NULL) - -gdm_xdmcp_chooser_slave_LDADD = \ - $(XLIB_LIBS) \ - $(DAEMON_LIBS) \ - $(EXTRA_DAEMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(JOURNALD_LIBS) \ - $(top_builddir)/common/libgdmcommon.la \ - $(NULL) - gdm_session_worker_SOURCES = \ session-worker-main.c \ gdm-session.c \ @@ -306,12 +190,28 @@ gdm_SOURCES = \ gdm-static-display.h \ gdm-transient-display.c \ gdm-transient-display.h \ + gdm-launch-environment.c \ + gdm-launch-environment.h \ gdm-manager.c \ gdm-manager.h \ - gdm-slave-job.c \ - gdm-slave-job.h \ + gdm-server.c \ + gdm-server.h \ + gdm-session.c \ + gdm-session.h \ + gdm-session-record.c \ + gdm-session-record.h \ + gdm-session-worker-common.c \ + gdm-session-worker-common.h \ + gdm-session-worker-job.c \ + gdm-session-worker-job.h \ + gdm-slave.c \ + gdm-slave.h \ + gdm-simple-slave.c \ + gdm-simple-slave.h \ gdm-dbus-util.c \ gdm-dbus-util.h \ + gdm-xerrors.c \ + gdm-xerrors.h \ $(NULL) nodist_gdm_SOURCES = \ @@ -325,8 +225,12 @@ nodist_gdm_SOURCES = \ gdm-transient-display-glue.c \ gdm-static-display-glue.h \ gdm-static-display-glue.c \ - gdm-slave-glue.h \ - gdm-slave-glue.c \ + gdm-session-glue.h \ + gdm-session-glue.c \ + gdm-session-worker-glue.c \ + gdm-session-worker-glue.h \ + gdm-session-enum-types.c \ + gdm-session-enum-types.h \ $(NULL) XDMCP_SOURCES = \ @@ -338,16 +242,12 @@ XDMCP_SOURCES = \ gdm-xdmcp-greeter-display.h \ gdm-xdmcp-chooser-display.c \ gdm-xdmcp-chooser-display.h \ - $(NULL) - -XDMCP_nodist_SOURCES = \ - gdm-xdmcp-chooser-slave-glue.c \ - gdm-xdmcp-chooser-slave-glue.h \ + gdm-xdmcp-chooser-slave.c \ + gdm-xdmcp-chooser-slave.h \ $(NULL) if XDMCP_SUPPORT gdm_SOURCES += $(XDMCP_SOURCES) -nodist_gdm_SOURCES += $(XDMCP_nodist_SOURCES) endif EXTRA_gdm_SOURCES = \ @@ -381,10 +281,8 @@ CLEANFILES = \ gdm-session-glue.c \ gdm-session-worker-glue.c \ gdm-session-enum-types.c \ - gdm-slave-glue.c \ gdm-static-display-glue.c \ gdm-transient-display-glue.c \ - gdm-xdmcp-chooser-slave-glue.c \ $(BUILT_SOURCES) \ $(NULL) diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index 3251bc38..be86f222 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -41,15 +41,11 @@ #include "gdm-settings-direct.h" #include "gdm-settings-keys.h" -#include "gdm-slave-job.h" -#include "gdm-slave-glue.h" +#include "gdm-simple-slave.h" #include "gdm-dbus-util.h" #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate)) -#define GDM_SLAVE_PATH "/org/gnome/DisplayManager/Slave" -#define DEFAULT_SLAVE_COMMAND LIBEXECDIR "/gdm-simple-slave" - struct GdmDisplayPrivate { char *id; @@ -62,7 +58,7 @@ struct GdmDisplayPrivate int status; time_t creation_time; GTimer *slave_timer; - char *slave_command; + GType slave_type; char *x11_cookie; gsize x11_cookie_size; @@ -71,10 +67,7 @@ struct GdmDisplayPrivate gboolean is_local; guint finish_idle_id; - GdmSlaveJob *slave_job; - char *slave_bus_name; - GdmDBusSlave *slave_proxy; - int slave_name_id; + GdmSlave *slave; GDBusConnection *connection; GdmDisplayAccessFile *user_access_file; @@ -96,7 +89,7 @@ enum { PROP_X11_COOKIE, PROP_X11_AUTHORITY_FILE, PROP_IS_LOCAL, - PROP_SLAVE_COMMAND, + PROP_SLAVE_TYPE, PROP_IS_INITIAL }; @@ -104,6 +97,8 @@ static void gdm_display_class_init (GdmDisplayClass *klass); static void gdm_display_init (GdmDisplay *display); static void gdm_display_finalize (GObject *object); static void queue_finish (GdmDisplay *display); +static void _gdm_display_set_status (GdmDisplay *display, + int status); G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT) @@ -289,79 +284,6 @@ gdm_display_add_user_authorization (GdmDisplay *display, } static void -on_name_vanished (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - queue_finish (GDM_DISPLAY (user_data)); -} - -static void -gdm_display_real_set_slave_bus_name_finish (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - GdmDisplay *display = user_data; - - display->priv->slave_proxy = GDM_DBUS_SLAVE (gdm_dbus_slave_proxy_new_finish (res, NULL)); - g_object_bind_property (G_OBJECT (display->priv->slave_proxy), - "session-id", - G_OBJECT (display), - "session-id", - G_BINDING_DEFAULT); -} - -static gboolean -gdm_display_real_set_slave_bus_name (GdmDisplay *display, - const char *name, - GError **error) -{ - g_free (display->priv->slave_bus_name); - display->priv->slave_bus_name = g_strdup (name); - - if (display->priv->slave_name_id > 0) { - g_bus_unwatch_name (display->priv->slave_name_id); - } - - display->priv->slave_name_id = g_bus_watch_name_on_connection (display->priv->connection, - name, - G_BUS_NAME_WATCHER_FLAGS_NONE, - NULL, /* name appeared */ - on_name_vanished, - g_object_ref (display), - NULL); - - g_clear_object (&display->priv->slave_proxy); - gdm_dbus_slave_proxy_new (display->priv->connection, - G_DBUS_PROXY_FLAGS_NONE, - name, - GDM_SLAVE_PATH, - NULL, - gdm_display_real_set_slave_bus_name_finish, - display); - - return TRUE; -} - -gboolean -gdm_display_set_slave_bus_name (GdmDisplay *display, - const char *name, - GError **error) -{ - gboolean ret; - - g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); - - g_debug ("GdmDisplay: Setting slave bus name:%s on display %s", name, display->priv->x11_display_name); - - g_object_ref (display); - ret = GDM_DISPLAY_GET_CLASS (display)->set_slave_bus_name (display, name, error); - g_object_unref (display); - - return ret; -} - -static void gdm_display_real_get_timed_login_details (GdmDisplay *display, gboolean *enabledp, char **usernamep, @@ -503,17 +425,19 @@ gdm_display_remove_user_authorization (GdmDisplay *display, } gboolean -gdm_display_get_x11_cookie (GdmDisplay *display, - GArray **x11_cookie, - GError **error) +gdm_display_get_x11_cookie (GdmDisplay *display, + const char **x11_cookie, + gsize *x11_cookie_size, + GError **error) { g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); if (x11_cookie != NULL) { - *x11_cookie = g_array_new (TRUE, FALSE, sizeof (char)); - g_array_append_vals (*x11_cookie, - display->priv->x11_cookie, - display->priv->x11_cookie_size); + *x11_cookie = display->priv->x11_cookie; + } + + if (x11_cookie_size != NULL) { + *x11_cookie_size = display->priv->x11_cookie_size; } return TRUE; @@ -610,26 +534,12 @@ queue_finish (GdmDisplay *display) } static void -slave_exited (GdmSlaveJob *job, - int code, - GdmDisplay *display) -{ - g_debug ("GdmDisplay: Slave exited: %d", code); - - queue_finish (display); -} - -static void -slave_died (GdmSlaveJob *job, - int signum, - GdmDisplay *display) +on_slave_stopped (GdmSlave *slave, + GdmDisplay *display) { - g_debug ("GdmDisplay: Slave died: %d", signum); - queue_finish (display); } - static void _gdm_display_set_status (GdmDisplay *display, int status) @@ -640,19 +550,20 @@ _gdm_display_set_status (GdmDisplay *display, } } +static void +on_slave_started (GdmSlave *slave, + GdmDisplay *display) +{ + _gdm_display_set_status (display, GDM_DISPLAY_MANAGED); +} + static gboolean gdm_display_real_prepare (GdmDisplay *display) { - char *command; - char *log_file; - char *log_path; - g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); g_debug ("GdmDisplay: prepare display"); - g_assert (display->priv->slave_job == NULL); - if (!gdm_display_create_authority (display)) { g_warning ("Unable to set up access control for display %d", display->priv->x11_display_number); @@ -661,28 +572,22 @@ gdm_display_real_prepare (GdmDisplay *display) _gdm_display_set_status (display, GDM_DISPLAY_PREPARED); - display->priv->slave_job = gdm_slave_job_new (); - g_signal_connect (display->priv->slave_job, - "exited", - G_CALLBACK (slave_exited), - display); - g_signal_connect (display->priv->slave_job, - "died", - G_CALLBACK (slave_died), - display); - - log_file = g_strdup_printf ("%s-slave.log", display->priv->x11_display_name); - log_path = g_build_filename (LOGDIR, log_file, NULL); - g_free (log_file); - gdm_slave_job_set_log_path (display->priv->slave_job, log_path); - g_free (log_path); - - command = g_strdup_printf ("%s --display-id %s", - display->priv->slave_command, - display->priv->id); - gdm_slave_job_set_command (display->priv->slave_job, command); - g_free (command); - + display->priv->slave = GDM_SLAVE (g_object_new (display->priv->slave_type, + "display", display, + NULL)); + g_signal_connect_object (display->priv->slave, "started", + G_CALLBACK (on_slave_started), + display, + 0); + g_signal_connect_object (display->priv->slave, "stopped", + G_CALLBACK (on_slave_stopped), + display, + 0); + g_object_bind_property (G_OBJECT (display->priv->slave), + "session-id", + G_OBJECT (display), + "session-id", + G_BINDING_DEFAULT); return TRUE; } @@ -719,11 +624,8 @@ gdm_display_real_manage (GdmDisplay *display) } } - g_assert (display->priv->slave_job != NULL); - g_timer_start (display->priv->slave_timer); - - gdm_slave_job_start (display->priv->slave_job); + gdm_slave_start (display->priv->slave); return TRUE; } @@ -783,11 +685,10 @@ gdm_display_real_unmanage (GdmDisplay *display) g_timer_stop (display->priv->slave_timer); - if (display->priv->slave_job != NULL) { - gdm_slave_job_stop (display->priv->slave_job); - - g_object_unref (display->priv->slave_job); - display->priv->slave_job = NULL; + if (display->priv->slave != NULL) { + gdm_slave_stop (display->priv->slave); + g_object_unref (display->priv->slave); + display->priv->slave = NULL; } if (display->priv->user_access_file != NULL) { @@ -810,11 +711,6 @@ gdm_display_real_unmanage (GdmDisplay *display) _gdm_display_set_status (display, GDM_DISPLAY_UNMANAGED); } - if (display->priv->slave_name_id > 0) { - g_bus_unwatch_name (display->priv->slave_name_id); - display->priv->slave_name_id = 0; - } - return TRUE; } @@ -939,11 +835,10 @@ _gdm_display_set_is_local (GdmDisplay *display, } static void -_gdm_display_set_slave_command (GdmDisplay *display, - const char *command) +_gdm_display_set_slave_type (GdmDisplay *display, + GType type) { - g_free (display->priv->slave_command); - display->priv->slave_command = g_strdup (command); + display->priv->slave_type = type; } static void @@ -991,8 +886,8 @@ gdm_display_set_property (GObject *object, case PROP_IS_LOCAL: _gdm_display_set_is_local (self, g_value_get_boolean (value)); break; - case PROP_SLAVE_COMMAND: - _gdm_display_set_slave_command (self, g_value_get_string (value)); + case PROP_SLAVE_TYPE: + _gdm_display_set_slave_type (self, g_value_get_gtype (value)); break; case PROP_IS_INITIAL: _gdm_display_set_is_initial (self, g_value_get_boolean (value)); @@ -1045,8 +940,8 @@ gdm_display_get_property (GObject *object, case PROP_IS_LOCAL: g_value_set_boolean (value, self->priv->is_local); break; - case PROP_SLAVE_COMMAND: - g_value_set_string (value, self->priv->slave_command); + case PROP_SLAVE_TYPE: + g_value_set_gtype (value, self->priv->slave_type); break; case PROP_IS_INITIAL: g_value_set_boolean (value, self->priv->is_initial); @@ -1149,18 +1044,18 @@ handle_get_x11_cookie (GdmDBusDisplay *skeleton, GDBusMethodInvocation *invocation, GdmDisplay *display) { - GArray *cookie = NULL; + const char *x11_cookie; + gsize x11_cookie_size; GVariant *variant; - gdm_display_get_x11_cookie (display, &cookie, NULL); + gdm_display_get_x11_cookie (display, &x11_cookie, &x11_cookie_size, NULL); variant = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - cookie->data, - cookie->len, + x11_cookie, + x11_cookie_size, sizeof (char)); gdm_dbus_display_complete_get_x11_cookie (skeleton, invocation, variant); - g_array_unref (cookie); return TRUE; } @@ -1222,41 +1117,6 @@ handle_is_initial (GdmDBusDisplay *skeleton, } static gboolean -handle_get_slave_bus_name (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *display) -{ - if (display->priv->slave_bus_name != NULL) { - gdm_dbus_display_complete_get_slave_bus_name (skeleton, invocation, - display->priv->slave_bus_name); - } else { - g_dbus_method_invocation_return_dbus_error (invocation, - "org.gnome.DisplayManager.NotReady", - "Slave is not yet registered"); - } - - return TRUE; -} - -static gboolean -handle_set_slave_bus_name (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - const char *bus_name, - GdmDisplay *display) -{ - GError *error = NULL; - - if (gdm_display_set_slave_bus_name (display, bus_name, &error)) { - gdm_dbus_display_complete_set_slave_bus_name (skeleton, invocation); - } else { - g_dbus_method_invocation_return_gerror (invocation, error); - g_error_free (error); - } - - return TRUE; -} - -static gboolean handle_add_user_authorization (GdmDBusDisplay *skeleton, GDBusMethodInvocation *invocation, const char *username, @@ -1332,10 +1192,6 @@ register_display (GdmDisplay *display) G_CALLBACK (handle_is_local), display); g_signal_connect (display->priv->display_skeleton, "handle-is-initial", G_CALLBACK (handle_is_initial), display); - g_signal_connect (display->priv->display_skeleton, "handle-get-slave-bus-name", - G_CALLBACK (handle_get_slave_bus_name), display); - g_signal_connect (display->priv->display_skeleton, "handle-set-slave-bus-name", - G_CALLBACK (handle_set_slave_bus_name), display); g_signal_connect (display->priv->display_skeleton, "handle-add-user-authorization", G_CALLBACK (handle_add_user_authorization), display); g_signal_connect (display->priv->display_skeleton, "handle-remove-user-authorization", @@ -1347,74 +1203,6 @@ register_display (GdmDisplay *display) return TRUE; } -char * -gdm_display_open_session_sync (GdmDisplay *display, - GPid pid_of_caller, - uid_t uid_of_caller, - GCancellable *cancellable, - GError **error) -{ - char *address; - int ret; - - if (display->priv->slave_proxy == NULL) { - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("No session available yet")); - return NULL; - } - - address = NULL; - ret = gdm_dbus_slave_call_open_session_sync (display->priv->slave_proxy, - (int) pid_of_caller, - (int) uid_of_caller, - &address, - cancellable, - error); - - if (!ret) { - return NULL; - } - - return address; -} - -char * -gdm_display_open_reauthentication_channel_sync (GdmDisplay *display, - const char *username, - GPid pid_of_caller, - uid_t uid_of_caller, - GCancellable *cancellable, - GError **error) -{ - char *address; - int ret; - - if (display->priv->slave_proxy == NULL) { - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("No session available yet")); - return NULL; - } - - address = NULL; - ret = gdm_dbus_slave_call_open_reauthentication_channel_sync (display->priv->slave_proxy, - username, - pid_of_caller, - uid_of_caller, - &address, - cancellable, - error); - - if (!ret) { - return NULL; - } - - return address; -} - /* dbus-send --system --print-reply --dest=org.gnome.DisplayManager /org/gnome/DisplayManager/Displays/1 org.freedesktop.DBus.Introspectable.Introspect */ @@ -1458,16 +1246,10 @@ gdm_display_dispose (GObject *object) g_debug ("GdmDisplay: Disposing display"); - if (display->priv->finish_idle_id > 0) { - g_source_remove (display->priv->finish_idle_id); - display->priv->finish_idle_id = 0; - } - - if (display->priv->slave_job != NULL) { - gdm_slave_job_stop (display->priv->slave_job); - - g_object_unref (display->priv->slave_job); - display->priv->slave_job = NULL; + if (display->priv->slave != NULL) { + gdm_slave_stop (display->priv->slave); + g_object_unref (display->priv->slave); + display->priv->slave = NULL; } if (display->priv->user_access_file != NULL) { @@ -1482,11 +1264,6 @@ gdm_display_dispose (GObject *object) display->priv->access_file = NULL; } - if (display->priv->slave_name_id > 0) { - g_bus_unwatch_name (display->priv->slave_name_id); - display->priv->slave_name_id = 0; - } - G_OBJECT_CLASS (gdm_display_parent_class)->dispose (object); } @@ -1504,7 +1281,6 @@ gdm_display_class_init (GdmDisplayClass *klass) klass->create_authority = gdm_display_real_create_authority; klass->add_user_authorization = gdm_display_real_add_user_authorization; klass->remove_user_authorization = gdm_display_real_remove_user_authorization; - klass->set_slave_bus_name = gdm_display_real_set_slave_bus_name; klass->get_timed_login_details = gdm_display_real_get_timed_login_details; klass->prepare = gdm_display_real_prepare; klass->manage = gdm_display_real_manage; @@ -1586,12 +1362,12 @@ gdm_display_class_init (GdmDisplayClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, - PROP_SLAVE_COMMAND, - g_param_spec_string ("slave-command", - "slave command", - "slave command", - DEFAULT_SLAVE_COMMAND, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + PROP_SLAVE_TYPE, + g_param_spec_gtype ("slave-type", + "slave type", + "slave type", + GDM_TYPE_SIMPLE_SLAVE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_STATUS, g_param_spec_int ("status", @@ -1633,8 +1409,6 @@ gdm_display_finalize (GObject *object) g_free (display->priv->remote_hostname); g_free (display->priv->x11_display_name); g_free (display->priv->x11_cookie); - g_free (display->priv->slave_command); - g_free (display->priv->slave_bus_name); g_clear_object (&display->priv->display_skeleton); g_clear_object (&display->priv->object_skeleton); @@ -1660,3 +1434,28 @@ gdm_display_get_object_skeleton (GdmDisplay *display) { return display->priv->object_skeleton; } + +void +gdm_display_set_up_greeter_session (GdmDisplay *display, + char **username) +{ + gdm_slave_set_up_greeter_session (display->priv->slave, username); +} + +void +gdm_display_start_greeter_session (GdmDisplay *display) +{ + gdm_slave_start_greeter_session (display->priv->slave); +} + +void +gdm_display_stop_greeter_session (GdmDisplay *display) +{ + gdm_slave_stop_greeter_session (display->priv->slave); +} + +GdmSlave * +gdm_display_get_slave (GdmDisplay *display) +{ + return display->priv->slave; +} diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h index 739be7dc..32fa290f 100644 --- a/daemon/gdm-display.h +++ b/daemon/gdm-display.h @@ -24,6 +24,7 @@ #include <glib-object.h> #include <gio/gio.h> +#include "gdm-slave.h" G_BEGIN_DECLS @@ -63,9 +64,6 @@ typedef struct gboolean (*remove_user_authorization) (GdmDisplay *display, const char *username, GError **error); - gboolean (*set_slave_bus_name) (GdmDisplay *display, - const char *name, - GError **error); gboolean (*prepare) (GdmDisplay *display); gboolean (*manage) (GdmDisplay *display); gboolean (*finish) (GdmDisplay *display); @@ -139,10 +137,10 @@ gboolean gdm_display_is_initial (GdmDisplay *dis gboolean *initial, GError **error); -/* exported but protected */ -gboolean gdm_display_get_x11_cookie (GdmDisplay *display, - GArray **x11_cookie, - GError **error); +gboolean gdm_display_get_x11_cookie (GdmDisplay *display, + const char **x11_cookie, + gsize *x11_cookie_size, + GError **error); gboolean gdm_display_get_x11_authority_file (GdmDisplay *display, char **filename, GError **error); @@ -153,9 +151,12 @@ gboolean gdm_display_add_user_authorization (GdmDisplay *disp gboolean gdm_display_remove_user_authorization (GdmDisplay *display, const char *username, GError **error); -gboolean gdm_display_set_slave_bus_name (GdmDisplay *display, - const char *name, - GError **error); + +void gdm_display_set_up_greeter_session (GdmDisplay *display, + char **username); +void gdm_display_start_greeter_session (GdmDisplay *display); +void gdm_display_stop_greeter_session (GdmDisplay *display); +GdmSlave * gdm_display_get_slave (GdmDisplay *display); G_END_DECLS diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml index 48d03dbe..bc279958 100644 --- a/daemon/gdm-display.xml +++ b/daemon/gdm-display.xml @@ -37,12 +37,6 @@ <method name="RemoveUserAuthorization"> <arg name="username" direction="in" type="s"/> </method> - <method name="GetSlaveBusName"> - <arg name="name" direction="out" type="s"/> - </method> - <method name="SetSlaveBusName"> - <arg name="name" direction="in" type="s"/> - </method> <method name="GetTimedLoginDetails"> <arg name="enabled" direction="out" type="b"/> <arg name="username" direction="out" type="s"/> diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index b1c61c23..21a30c6a 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -46,6 +46,7 @@ #include "gdm-display-store.h" #include "gdm-display-factory.h" #include "gdm-local-display-factory.h" +#include "gdm-session.h" #include "gdm-xdmcp-display-factory.h" #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate)) @@ -54,6 +55,15 @@ #define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager" #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" +#define CK_NAME "org.freedesktop.ConsoleKit" +#define CK_PATH "/org/freedesktop/ConsoleKit" +#define CK_INTERFACE "org.freedesktop.ConsoleKit" + +#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" +#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" +#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" +#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" + struct GdmManagerPrivate { GdmDisplayStore *display_store; @@ -61,7 +71,10 @@ struct GdmManagerPrivate #ifdef HAVE_LIBXDMCP GdmXdmcpDisplayFactory *xdmcp_factory; #endif + GList *user_sessions; + GHashTable *open_reauthentication_requests; gboolean xdmcp_enabled; + GCancellable *cancellable; gboolean started; gboolean wait_for_go; @@ -89,6 +102,9 @@ 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 create_session_for_display (GdmManager *manager, + GdmDisplay *display, + uid_t allowed_user); static gpointer manager_object = NULL; @@ -266,6 +282,205 @@ lookup_by_session_id (const char *id, return g_strcmp0 (current, looking_for) == 0; } +#ifdef WITH_SYSTEMD +static gboolean +activate_session_id_for_systemd (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; +} +#endif + +#ifdef WITH_CONSOLE_KIT +static gboolean +activate_session_id_for_ck (GdmManager *manager, + const char *seat_id, + const char *session_id) +{ + GError *error = NULL; + GVariant *reply; + + reply = g_dbus_connection_call_sync (manager->priv->connection, + CK_NAME, + seat_id, + "org.freedesktop.ConsoleKit.Seat", + "ActivateSession", + g_variant_new ("(o)", session_id), + NULL, /* expected reply */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (reply == NULL) { + g_debug ("GdmManager: ConsoleKit %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; +} +#endif + +static gboolean +activate_session_id (GdmManager *manager, + const char *seat_id, + const char *session_id) +{ + +#ifdef WITH_SYSTEMD + if (LOGIND_RUNNING()) { + return activate_session_id_for_systemd (manager, seat_id, session_id); + } +#endif + +#ifdef WITH_CONSOLE_KIT + return activate_session_id_for_ck (manager, seat_id, session_id); +#else + return FALSE; +#endif +} + +#ifdef WITH_SYSTEMD +static gboolean +session_unlock_for_systemd (GdmManager *manager, + const char *ssid) +{ + GError *error = NULL; + GVariant *reply; + + reply = g_dbus_connection_call_sync (manager->priv->connection, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "UnlockSession", + g_variant_new ("(s)", ssid), + NULL, /* expected reply */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (reply == NULL) { + g_debug ("GdmManager: logind 'UnlockSession' %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; +} +#endif + +#ifdef WITH_CONSOLE_KIT +static gboolean +session_unlock_for_ck (GdmManager *manager, + const char *ssid) +{ + GError *error = NULL; + GVariant *reply; + + reply = g_dbus_connection_call_sync (manager->priv->connection, + CK_NAME, + ssid, + CK_SESSION_INTERFACE, + "Unlock", + NULL, /* parameters */ + NULL, /* expected reply */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (reply == NULL) { + g_debug ("GdmManager: ConsoleKit %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; +} +#endif + +static gboolean +session_unlock (GdmManager *manager, + const char *ssid) +{ + + g_debug ("Unlocking session %s", ssid); + +#ifdef WITH_SYSTEMD + if (LOGIND_RUNNING()) { + return session_unlock_for_systemd (manager, ssid); + } +#endif + +#ifdef WITH_CONSOLE_KIT + return session_unlock_for_ck (manager, ssid); +#else + return TRUE; +#endif +} + +static GdmSession * +find_session_for_user_on_seat (GdmManager *manager, + const char *username, + const char *seat_id, + GdmSession *dont_count_session) +{ + GList *node; + + for (node = manager->priv->user_sessions; node != NULL; node = node->next) { + GdmSession *candidate_session = node->data; + const char *candidate_username, *candidate_seat_id; + + if (candidate_session == dont_count_session) + continue; + + if (!gdm_session_is_running (candidate_session)) + continue; + + candidate_username = gdm_session_get_username (candidate_session); + candidate_seat_id = gdm_session_get_display_seat_id (candidate_session); + + if (g_strcmp0 (candidate_username, username) == 0 && + g_strcmp0 (candidate_seat_id, seat_id) == 0) { + return candidate_session; + } + } + + return NULL; +} + static GdmDisplay * get_display_and_details_for_bus_sender (GdmManager *self, GDBusConnection *connection, @@ -322,6 +537,7 @@ get_display_and_details_for_bus_sender (GdmManager *self, display = gdm_display_store_find (self->priv->display_store, lookup_by_session_id, (gpointer) session_id); + out: g_free (session_id); @@ -336,17 +552,80 @@ out: } 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; + } + + 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_user_session_for_display (GdmDisplay *display) +{ + if (display == NULL) { + return NULL; + } + + return g_object_get_data (G_OBJECT (display), "gdm-session"); +} + +static gboolean gdm_manager_handle_open_session (GdmDBusManager *manager, GDBusMethodInvocation *invocation) { GdmManager *self = GDM_MANAGER (manager); - const char *sender = NULL; + const char *sender; GError *error = NULL; GDBusConnection *connection; GdmDisplay *display; - char *address; + GdmSession *session; + const char *address; GPid pid; - uid_t uid; + uid_t uid, allowed_user; g_debug ("GdmManager: trying to open new session"); @@ -363,7 +642,25 @@ gdm_manager_handle_open_session (GdmDBusManager *manager, return TRUE; } - address = gdm_display_open_session_sync (display, pid, uid, NULL, &error); + session = get_user_session_for_display (display); + + if (gdm_session_is_running (session)) { + error = g_error_new (G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + _("Can only be called before user is logged in")); + return FALSE; + } + + allowed_user = gdm_session_get_allowed_user (session); + + if (uid != allowed_user) { + error = g_error_new (G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + _("Caller not GDM")); + return FALSE; + } + + address = gdm_session_get_server_address (session); if (address == NULL) { g_dbus_method_invocation_return_gerror (invocation, error); @@ -374,8 +671,6 @@ gdm_manager_handle_open_session (GdmDBusManager *manager, gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager), invocation, address); - g_free (address); - return TRUE; } @@ -385,11 +680,10 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager const char *username) { GdmManager *self = GDM_MANAGER (manager); - const char *sender = NULL; - GError *error = NULL; - GDBusConnection *connection; + const char *sender; GdmDisplay *display; - char *address; + GdmSession *session; + GDBusConnection *connection; GPid pid; uid_t uid; @@ -408,23 +702,22 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager return TRUE; } - address = gdm_display_open_reauthentication_channel_sync (display, - username, - pid, - uid, - NULL, - &error); + session = get_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, + _("No session available")); - if (address == NULL) { - g_dbus_method_invocation_return_gerror (invocation, error); - g_error_free (error); return TRUE; } - gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), - invocation, - address); - g_free (address); + gdm_session_start_reauthentication (session, pid, uid); + + g_hash_table_insert (self->priv->open_reauthentication_requests, + GINT_TO_POINTER (pid), + invocation); return TRUE; } @@ -437,6 +730,51 @@ manager_interface_init (GdmDBusManagerIface *interface) } static void +set_up_greeter_session (GdmManager *manager, + GdmDisplay *display) +{ + char *allowed_user; + struct passwd *passwd_entry; + + gdm_display_set_up_greeter_session (display, &allowed_user); + + if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { + g_warning ("GdmManager: couldn't look up username %s", + allowed_user); + gdm_display_finish (display); + return; + } + + create_session_for_display (manager, display, passwd_entry->pw_uid); + g_free (allowed_user); + + gdm_display_start_greeter_session (display); +} + +static void +on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmManager *manager) +{ + int status; + + status = gdm_display_get_status (display); + + switch (status) { + case GDM_DISPLAY_MANAGED: + set_up_greeter_session (manager, display); + break; + case GDM_DISPLAY_FAILED: + case GDM_DISPLAY_UNMANAGED: + case GDM_DISPLAY_FINISHED: + break; + default: + break; + } + +} + +static void on_display_removed (GdmDisplayStore *display_store, const char *id, GdmManager *manager) @@ -444,14 +782,692 @@ on_display_removed (GdmDisplayStore *display_store, GdmDisplay *display; display = gdm_display_store_lookup (display_store, id); - if (display != NULL) { g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); + g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); + g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id); } } +typedef struct +{ + GdmManager *manager; + GdmSession *session; + char *service_name; + guint idle_id; +} StartUserSessionOperation; + +static void +destroy_start_user_session_operation (StartUserSessionOperation *operation) +{ + g_object_set_data (G_OBJECT (operation->session), + "start-user-session-operation", + NULL); + g_object_unref (operation->session); + g_free (operation->service_name); + g_slice_free (StartUserSessionOperation, operation); +} + +static void +start_user_session (GdmManager *manager, + StartUserSessionOperation *operation) +{ + GdmDisplay *display; + + display = get_display_for_user_session (operation->session); + + if (display != NULL) { + char *auth_file; + const char *username; + + auth_file = NULL; + username = gdm_session_get_username (operation->session); + gdm_display_add_user_authorization (display, + username, + &auth_file, + NULL); + + g_assert (auth_file != NULL); + + g_object_set (operation->session, + "user-x11-authority-file", auth_file, + NULL); + + g_free (auth_file); + } + + gdm_session_start_session (operation->session, + operation->service_name); + destroy_start_user_session_operation (operation); +} + +static gboolean +on_start_user_session (StartUserSessionOperation *operation) +{ + gboolean migrated; + gboolean fail_if_already_switched = TRUE; + + 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); + } else { + GdmDisplay *display; + + display = get_display_for_user_session (operation->session); + gdm_display_stop_greeter_session (display); + + start_user_session (operation->manager, operation); + } + + 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 +start_user_session_if_ready (GdmManager *manager, + GdmSession *session, + const char *service_name) +{ + gboolean start_when_ready; + + start_when_ready = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), "start-when-ready")); + if (start_when_ready) { + g_object_set_data (G_OBJECT (session), "waiting-to-start", GINT_TO_POINTER (FALSE)); + queue_start_user_session (manager, session, service_name); + } else { + g_object_set_data (G_OBJECT (session), "waiting-to-start", GINT_TO_POINTER (TRUE)); + } +} + +static void +on_session_opened (GdmSession *session, + const char *service_name, + const char *session_id, + GdmManager *manager) +{ + manager->priv->user_sessions = g_list_append (manager->priv->user_sessions, + g_object_ref (session)); + if (g_strcmp0 (service_name, "gdm-autologin") == 0 && + !gdm_session_client_is_connected (session)) { + /* If we're auto logging in then don't wait for the go-ahead from a greeter, + * (since there is no greeter) */ + g_object_set_data (G_OBJECT (session), "start-when-ready", GINT_TO_POINTER (TRUE)); + } + + start_user_session_if_ready (manager, session, service_name); +} + +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_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, + NULL); + + error = NULL; + command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s", + display_name); + g_free (display_name); + + g_debug ("GdmManager: Running helper %s", command); + out = NULL; + res = g_spawn_command_line_sync (command, + &out, + NULL, + &status, + &error); + if (! res) { + g_warning ("GdmManager: Could not run helper %s: %s", command, error->message); + g_error_free (error); + } else { + out = g_strstrip (out); + g_debug ("GdmManager: Got tty: '%s'", out); + } + + g_free (command); + + return out; +} + +static char * +get_display_device (GdmManager *manager, + GdmDisplay *display) +{ +#ifdef WITH_SYSTEMD + if (LOGIND_RUNNING()) { + /* systemd finds the display device out on its own based on the display */ + return NULL; + } +#endif + + return query_ck_for_display_device (manager, display); +} + +static void +on_ready_to_request_timed_login (GdmSession *session, + GSimpleAsyncResult *result, + gpointer *user_data) +{ + int delay = GPOINTER_TO_INT (user_data); + GCancellable *cancellable; + char *username; + + cancellable = g_object_get_data (G_OBJECT (result), + "cancellable"); + if (g_cancellable_is_cancelled (cancellable)) { + return; + } + + username = g_simple_async_result_get_source_tag (result); + + gdm_session_request_timed_login (session, username, delay); + + g_object_weak_unref (G_OBJECT (session), + (GWeakNotify) + g_cancellable_cancel, + cancellable); + g_object_weak_unref (G_OBJECT (session), + (GWeakNotify) + g_object_unref, + cancellable); + g_object_weak_unref (G_OBJECT (session), + (GWeakNotify) + g_free, + username); + + g_free (username); +} + +static gboolean +on_wait_for_greeter_timeout (GSimpleAsyncResult *result) +{ + g_simple_async_result_complete (result); + + return FALSE; +} + +static void +on_session_reauthenticated (GdmSession *session, + const char *service_name, + GdmManager *manager) +{ + gboolean fail_if_already_switched = FALSE; + /* 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), + * then silently succeed and unlock the session. + */ + switch_to_compatible_user_session (manager, session, fail_if_already_switched); +} + +static void +on_session_client_ready_for_session_to_start (GdmSession *session, + const char *service_name, + gboolean client_is_ready, + GdmManager *manager) +{ + gboolean waiting_to_start_user_session; + + if (client_is_ready) { + g_debug ("GdmManager: Will start session when ready"); + } else { + g_debug ("GdmManager: Will start session when ready and told"); + } + + waiting_to_start_user_session = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), + "waiting-to-start")); + + g_object_set_data (G_OBJECT (session), + "start-when-ready", + GINT_TO_POINTER (client_is_ready)); + + if (client_is_ready && waiting_to_start_user_session) { + start_user_session_if_ready (manager, session, service_name); + } +} + +static void +on_session_client_connected (GdmSession *session, + GCredentials *credentials, + GPid pid_of_client, + GdmManager *manager) +{ + GdmDisplay *display; + gboolean timed_login_enabled; + char *username; + int delay; + gboolean enabled, display_is_local; + + g_debug ("GdmManager: client connected"); + + display = get_display_for_user_session (session); + + if (display == NULL) { + return; + } + + g_object_get (display, "is-local", &display_is_local, NULL); + + timed_login_enabled = FALSE; + gdm_display_get_timed_login_details (display, &enabled, &username, &delay, NULL); + + if (! timed_login_enabled) { + return; + } + + /* temporary hack to fix timed login + * http://bugzilla.gnome.org/680348 + */ + if (delay > 0) { + GSimpleAsyncResult *result; + GCancellable *cancellable; + guint timeout_id; + gpointer source_tag; + + delay = MAX (delay, 4); + + cancellable = g_cancellable_new (); + source_tag = g_strdup (username); + result = g_simple_async_result_new (G_OBJECT (session), + (GAsyncReadyCallback) + on_ready_to_request_timed_login, + GINT_TO_POINTER (delay), + source_tag); + g_simple_async_result_set_check_cancellable (result, cancellable); + g_object_set_data (G_OBJECT (result), + "cancellable", + cancellable); + + timeout_id = g_timeout_add_seconds_full (delay - 2, + G_PRIORITY_DEFAULT, + (GSourceFunc) + on_wait_for_greeter_timeout, + g_object_ref (result), + (GDestroyNotify) + g_object_unref); + g_cancellable_connect (cancellable, + G_CALLBACK (g_source_remove), + GINT_TO_POINTER (timeout_id), + NULL); + + g_object_weak_ref (G_OBJECT (session), + (GWeakNotify) + g_cancellable_cancel, + cancellable); + g_object_weak_ref (G_OBJECT (session), + (GWeakNotify) + g_object_unref, + cancellable); + g_object_weak_ref (G_OBJECT (session), + (GWeakNotify) + g_free, + source_tag); + } + + 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 +queue_session_reset (GdmManager *manager, + GdmSession *session) +{ + ResetSessionOperation *operation; + + operation = g_object_get_data (G_OBJECT (session), "reset-session-operation"); + + if (operation != NULL) { + return; + } + + operation = g_slice_new0 (ResetSessionOperation); + operation->manager = manager; + operation->session = g_object_ref (session); + operation->idle_id = g_idle_add ((GSourceFunc) on_reset_session, operation); + + g_object_set_data (G_OBJECT (session), "reset-session-operation", operation); +} + +static void +on_session_cancelled (GdmSession *session, + GdmManager *manager) +{ + g_debug ("GdmManager: Session was cancelled"); + queue_session_reset (manager, session); +} + +static void +on_session_conversation_started (GdmSession *session, + const char *service_name, + GdmManager *manager) +{ + GdmDisplay *display; + gboolean enabled; + char *username; + int delay; + + g_debug ("GdmManager: session conversation started for service %s", service_name); + + if (g_strcmp0 (service_name, "gdm-autologin") != 0) { + return; + } + + display = get_display_for_user_session (session); + + if (display == NULL) { + g_debug ("GdmManager: conversation has no associated display"); + return; + } + + enabled = FALSE; + gdm_display_get_timed_login_details (display, &enabled, &username, &delay, NULL); + if (! enabled) { + return; + } + + if (delay == 0) { + g_debug ("GdmManager: begin auto login for user '%s'", username); + /* service_name will be "gdm-autologin" + */ + gdm_session_setup_for_user (session, service_name, username); + } + + g_free (username); +} + +static void +on_session_conversation_stopped (GdmSession *session, + const char *service_name, + GdmManager *manager) +{ + g_debug ("GdmManager: session conversation '%s' stopped", service_name); +} + +static void +on_session_reauthentication_started (GdmSession *session, + int pid_of_caller, + const char *address, + GdmManager *manager) +{ + GDBusMethodInvocation *invocation; + gpointer source_tag; + + g_debug ("GdmManager: reauthentication started"); + + source_tag = GINT_TO_POINTER (pid_of_caller); + + invocation = g_hash_table_lookup (manager->priv->open_reauthentication_requests, + source_tag); + + if (invocation != NULL) { + gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), + invocation, + address); + } + + g_hash_table_remove (manager->priv->open_reauthentication_requests, + source_tag); +} + +static void +start_autologin_conversation_if_necessary (GdmManager *manager, + GdmDisplay *display, + GdmSession *session) +{ + gboolean enabled; + + if (g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) { + return; + } + + gdm_display_get_timed_login_details (display, &enabled, NULL, NULL, NULL); + + if (!enabled) { + return; + } + + g_debug ("GdmManager: Starting automatic login conversation"); + gdm_session_start_conversation (session, "gdm-autologin"); +} + +static void +touch_marker_file (GdmManager *manager) +{ + int fd; + + fd = g_creat (GDM_RAN_ONCE_MARKER_FILE, 0644); + + if (fd < 0 && errno != EEXIST) { + g_warning ("could not create %s to mark run, this may cause auto login " + "to repeat: %m", GDM_RAN_ONCE_MARKER_FILE); + return; + } + + fsync (fd); + close (fd); +} + +static void +create_session_for_display (GdmManager *manager, + GdmDisplay *display, + uid_t allowed_user) +{ + GdmSession *session; + gboolean display_is_local = FALSE; + char *display_name = NULL; + char *display_device = NULL; + char *remote_hostname = NULL; + char *display_auth_file = NULL; + char *display_seat_id = NULL; + char *display_id = NULL; + + g_object_get (G_OBJECT (display), + "id", &display_id, + "x11-display-name", &display_name, + "is-local", &display_is_local, + "remote-hostname", &remote_hostname, + "x11-authority-file", &display_auth_file, + "seat-id", &display_seat_id, + NULL); + display_device = get_display_device (manager, display); + + session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN, + allowed_user, + display_name, + remote_hostname, + display_device, + display_seat_id, + display_auth_file, + display_is_local, + NULL); + g_free (display_name); + g_free (remote_hostname); + g_free (display_auth_file); + g_free (display_seat_id); + + g_signal_connect (session, + "reauthentication-started", + G_CALLBACK (on_session_reauthentication_started), + manager); + g_signal_connect (session, + "reauthenticated", + G_CALLBACK (on_session_reauthenticated), + manager); + g_signal_connect (session, + "client-ready-for-session-to-start", + G_CALLBACK (on_session_client_ready_for_session_to_start), + 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-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-session", g_object_ref (session), (GDestroyNotify) g_object_unref); + + start_autologin_conversation_if_necessary (manager, display, session); + touch_marker_file (manager); +} + static void on_display_added (GdmDisplayStore *display_store, const char *id, @@ -464,6 +1480,10 @@ on_display_added (GdmDisplayStore *display_store, 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); } } @@ -768,7 +1788,13 @@ gdm_manager_init (GdmManager *manager) manager->priv = GDM_MANAGER_GET_PRIVATE (manager); manager->priv->display_store = gdm_display_store_new (); - + manager->priv->user_sessions = NULL; + manager->priv->open_reauthentication_requests = g_hash_table_new_full (NULL, + NULL, + (GDestroyNotify) + NULL, + (GDestroyNotify) + g_object_unref); g_signal_connect (G_OBJECT (manager->priv->display_store), "display-added", G_CALLBACK (on_display_added), @@ -805,6 +1831,9 @@ gdm_manager_finalize (GObject *object) 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_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), diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c index 02f4dc92..04212d2c 100644 --- a/daemon/gdm-simple-slave.c +++ b/daemon/gdm-simple-slave.c @@ -57,9 +57,6 @@ #define GDM_SIMPLE_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SIMPLE_SLAVE, GdmSimpleSlavePrivate)) -#define GDM_DBUS_NAME "org.gnome.DisplayManager" -#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display" - #define MAX_CONNECT_ATTEMPTS 10 #define DEFAULT_PING_INTERVAL 15 @@ -69,10 +66,8 @@ struct GdmSimpleSlavePrivate { GPid pid; + char *username; gint greeter_reset_id; - guint start_session_id; - - char *start_session_service_name; int ping_interval; @@ -81,22 +76,14 @@ struct GdmSimpleSlavePrivate GdmServer *server; - /* we control the user session */ - GdmSession *session; - /* this spawns and controls the greeter session */ GdmLaunchEnvironment *greeter_environment; - GHashTable *open_reauthentication_requests; - GDBusProxy *accountsservice_proxy; guint have_existing_user_accounts : 1; guint accountsservice_ready : 1; guint waiting_to_connect_to_display : 1; - guint start_session_when_ready : 1; - guint waiting_to_start_session : 1; - guint session_is_running : 1; #ifdef HAVE_LOGINDEVPERM gboolean use_logindevperm; #endif @@ -113,22 +100,10 @@ enum { static void gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass); static void gdm_simple_slave_init (GdmSimpleSlave *simple_slave); static void gdm_simple_slave_finalize (GObject *object); -static void gdm_simple_slave_open_reauthentication_channel (GdmSlave *slave, - const char *username, - GPid pid_of_caller, - uid_t uid_of_caller, - GAsyncReadyCallback callback, - gpointer user_data, - GCancellable *cancellable); static gboolean wants_initial_setup (GdmSimpleSlave *slave); G_DEFINE_TYPE (GdmSimpleSlave, gdm_simple_slave, GDM_TYPE_SLAVE) -static void create_new_session (GdmSimpleSlave *slave); -static void start_session (GdmSimpleSlave *slave); -static void queue_start_session (GdmSimpleSlave *slave, - const char *service_name); - static gboolean chown_file (GFile *file, uid_t uid, @@ -246,22 +221,6 @@ out: g_free (gis_dir_path); } -static void -on_session_started (GdmSession *session, - const char *service_name, - int pid, - GdmSimpleSlave *slave) -{ - const char *session_id; - - g_debug ("GdmSimpleSlave: session started %d", pid); - - slave->priv->session_is_running = TRUE; - - session_id = gdm_session_get_session_id (session); - g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL); -} - #ifdef HAVE_LOGINDEVPERM static void gdm_simple_slave_grant_console_permissions (GdmSimpleSlave *slave) @@ -330,599 +289,6 @@ gdm_simple_slave_revoke_console_permissions (GdmSimpleSlave *slave) #endif /* HAVE_LOGINDEVPERM */ static void -on_session_exited (GdmSession *session, - int exit_code, - GdmSimpleSlave *slave) -{ - g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL); - - g_debug ("GdmSimpleSlave: session exited with code %d\n", exit_code); - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static void -on_session_died (GdmSession *session, - int signal_number, - GdmSimpleSlave *slave) -{ - g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL); - - g_debug ("GdmSimpleSlave: session died with signal %d, (%s)", - signal_number, - g_strsignal (signal_number)); - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static gboolean -add_user_authorization (GdmSimpleSlave *slave, - char **filename) -{ - const char *username; - gboolean ret; - - username = gdm_session_get_username (slave->priv->session); - ret = gdm_slave_add_user_authorization (GDM_SLAVE (slave), - username, - filename); - - return ret; -} - -static void -reset_session (GdmSimpleSlave *slave) -{ - if (slave->priv->session == NULL) { - return; - } - - gdm_session_reset (slave->priv->session); -} - -static gboolean -greeter_reset_timeout (GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: resetting greeter"); - - reset_session (slave); - - slave->priv->greeter_reset_id = 0; - return FALSE; -} - -static void -queue_greeter_reset (GdmSimpleSlave *slave) -{ - if (slave->priv->greeter_reset_id > 0) { - return; - } - - slave->priv->greeter_reset_id = g_idle_add ((GSourceFunc)greeter_reset_timeout, slave); -} - -static void -gdm_simple_slave_start_session_when_ready (GdmSimpleSlave *slave, - const char *service_name) -{ - if (slave->priv->start_session_when_ready) { - slave->priv->waiting_to_start_session = FALSE; - queue_start_session (slave, service_name); - } else { - slave->priv->waiting_to_start_session = TRUE; - } -} - -static gboolean -switch_to_and_unlock_session (GdmSimpleSlave *slave, - gboolean fail_if_already_switched) -{ - const char *username; - const char *session_id; - gboolean res; - - username = gdm_session_get_username (slave->priv->session); - session_id = gdm_session_get_session_id (slave->priv->session); - - g_debug ("GdmSimpleSlave: trying to switch to session for user %s", username); - - /* try to switch to an existing session */ - res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username, session_id, fail_if_already_switched); - - return res; -} - -static void -stop_greeter (GdmSimpleSlave *slave) -{ - gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment)); -} - -static void -start_session (GdmSimpleSlave *slave) -{ - char *auth_file; - - auth_file = NULL; - add_user_authorization (slave, &auth_file); - - g_assert (auth_file != NULL); - - g_object_set (slave->priv->session, - "user-x11-authority-file", auth_file, - NULL); - - g_free (auth_file); - - if (slave->priv->doing_initial_setup) { - chown_initial_setup_home_dir (); - } - - gdm_session_start_session (slave->priv->session, - slave->priv->start_session_service_name); - - slave->priv->start_session_id = 0; - g_free (slave->priv->start_session_service_name); - slave->priv->start_session_service_name = NULL; -} - -static gboolean -start_session_timeout (GdmSimpleSlave *slave) -{ - gboolean migrated; - gboolean fail_if_already_switched = TRUE; - - g_debug ("GdmSimpleSlave: accredited"); - - /* 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. - * - * We assume we're in the former case if we need to switch - * VTs, and we assume we're in the latter case if we don't. - */ - migrated = switch_to_and_unlock_session (slave, fail_if_already_switched); - g_debug ("GdmSimpleSlave: migrated: %d", migrated); - if (migrated) { - /* We don't stop the slave here because - when Xorg exits it switches to the VT it was - started from. That interferes with fast - user switching. */ - gdm_session_reset (slave->priv->session); - - slave->priv->start_session_id = 0; - g_free (slave->priv->start_session_service_name); - slave->priv->start_session_service_name = NULL; - } else { - if (slave->priv->greeter_environment == NULL) { - /* auto login */ - start_session (slave); - } else { - /* Session actually gets started from on_greeter_environment_session_stop */ - stop_greeter (slave); - } - } - - return FALSE; -} - -static void -queue_start_session (GdmSimpleSlave *slave, - const char *service_name) -{ - if (slave->priv->start_session_id > 0) { - return; - } - - slave->priv->start_session_id = g_idle_add ((GSourceFunc)start_session_timeout, slave); - slave->priv->start_session_service_name = g_strdup (service_name); -} - -static void -on_session_reauthenticated (GdmSession *session, - const char *service_name, - GdmSimpleSlave *slave) -{ - gboolean fail_if_already_switched = FALSE; - - /* There should already be a session running, so jump to it's - * 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), - * then silently succeed and unlock the session. - */ - switch_to_and_unlock_session (slave, fail_if_already_switched); -} - -static void -on_session_opened (GdmSession *session, - const char *service_name, - const char *session_id, - GdmSimpleSlave *slave) -{ - -#ifdef HAVE_LOGINDEVPERM - gdm_simple_slave_grant_console_permissions (slave); -#endif /* HAVE_LOGINDEVPERM */ - - if (g_strcmp0 (service_name, "gdm-autologin") == 0 && - !gdm_session_client_is_connected (slave->priv->session)) { - /* If we're auto logging in then don't wait for the go-ahead from a greeter, - * (since there is no greeter) */ - slave->priv->start_session_when_ready = TRUE; - } - - gdm_simple_slave_start_session_when_ready (slave, service_name); -} - -static void -on_session_conversation_started (GdmSession *session, - const char *service_name, - GdmSimpleSlave *slave) -{ - gboolean enabled; - char *username; - int delay; - - g_debug ("GdmSimpleSlave: session conversation started for service %s", service_name); - - if (g_strcmp0 (service_name, "gdm-autologin") != 0) { - return; - } - - enabled = FALSE; - gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay); - if (! enabled) { - return; - } - - if (delay == 0) { - g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username); - /* service_name will be "gdm-autologin" - */ - gdm_session_setup_for_user (slave->priv->session, service_name, username); - } - - g_free (username); -} - -static void -on_session_conversation_stopped (GdmSession *session, - const char *service_name, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: conversation stopped"); - -} - -static void -start_autologin_conversation_if_necessary (GdmSimpleSlave *slave) -{ - gboolean enabled; - - if (g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) { - return; - } - - gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, NULL); - - if (!enabled) { - return; - } - - g_debug ("GdmSimpleSlave: Starting automatic login conversation"); - gdm_session_start_conversation (slave->priv->session, "gdm-autologin"); -} - -static void -on_session_reauthentication_started (GdmSession *session, - int pid_of_caller, - const char *address, - GdmSimpleSlave *slave) -{ - GSimpleAsyncResult *result; - gpointer source_tag; - - g_debug ("GdmSimpleSlave: reauthentication started"); - - source_tag = GINT_TO_POINTER (pid_of_caller); - - result = g_hash_table_lookup (slave->priv->open_reauthentication_requests, - source_tag); - - if (result != NULL) { - g_simple_async_result_set_op_res_gpointer (result, - g_strdup (address), - (GDestroyNotify) - g_free); - g_simple_async_result_complete_in_idle (result); - } - - g_hash_table_remove (slave->priv->open_reauthentication_requests, - source_tag); -} - -static void -on_session_client_ready_for_session_to_start (GdmSession *session, - const char *service_name, - gboolean client_is_ready, - GdmSimpleSlave *slave) -{ - if (client_is_ready) { - g_debug ("GdmSimpleSlave: Will start session when ready"); - } else { - g_debug ("GdmSimpleSlave: Will start session when ready and told"); - } - - if (slave->priv->greeter_reset_id > 0) { - return; - } - - slave->priv->start_session_when_ready = client_is_ready; - - if (client_is_ready && slave->priv->waiting_to_start_session) { - gdm_simple_slave_start_session_when_ready (slave, service_name); - } -} - -static void -on_ready_to_request_timed_login (GdmSession *session, - GSimpleAsyncResult *result, - gpointer *user_data) -{ - int delay = GPOINTER_TO_INT (user_data); - GCancellable *cancellable; - char *username; - - cancellable = g_object_get_data (G_OBJECT (result), - "cancellable"); - if (g_cancellable_is_cancelled (cancellable)) { - return; - } - - username = g_simple_async_result_get_source_tag (result); - - gdm_session_request_timed_login (session, username, delay); - - g_object_weak_unref (G_OBJECT (session), - (GWeakNotify) - g_cancellable_cancel, - cancellable); - g_object_weak_unref (G_OBJECT (session), - (GWeakNotify) - g_object_unref, - cancellable); - g_object_weak_unref (G_OBJECT (session), - (GWeakNotify) - g_free, - username); - - g_free (username); -} - -static gboolean -on_wait_for_greeter_timeout (GSimpleAsyncResult *result) -{ - g_simple_async_result_complete (result); - - return FALSE; -} - -static void -on_session_client_connected (GdmSession *session, - GCredentials *credentials, - GPid pid_of_client, - GdmSimpleSlave *slave) -{ - gboolean timed_login_enabled; - char *username; - int delay; - gboolean display_is_local; - - g_debug ("GdmSimpleSlave: client connected"); - - g_object_get (slave, - "display-is-local", &display_is_local, - NULL); - - /* If XDMCP stop pinging */ - if ( ! display_is_local) { - alarm (0); - } - - timed_login_enabled = FALSE; - gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &timed_login_enabled, &username, &delay); - - if (! timed_login_enabled) { - return; - } - - /* temporary hack to fix timed login - * http://bugzilla.gnome.org/680348 - */ - if (delay > 0) { - GSimpleAsyncResult *result; - GCancellable *cancellable; - guint timeout_id; - gpointer source_tag; - - delay = MAX (delay, 4); - - cancellable = g_cancellable_new (); - source_tag = g_strdup (username); - result = g_simple_async_result_new (G_OBJECT (session), - (GAsyncReadyCallback) - on_ready_to_request_timed_login, - GINT_TO_POINTER (delay), - source_tag); - g_simple_async_result_set_check_cancellable (result, cancellable); - g_object_set_data (G_OBJECT (result), - "cancellable", - cancellable); - - timeout_id = g_timeout_add_seconds_full (delay - 2, - G_PRIORITY_DEFAULT, - (GSourceFunc) - on_wait_for_greeter_timeout, - g_object_ref (result), - (GDestroyNotify) - g_object_unref); - g_cancellable_connect (cancellable, - G_CALLBACK (g_source_remove), - GINT_TO_POINTER (timeout_id), - NULL); - - g_object_weak_ref (G_OBJECT (session), - (GWeakNotify) - g_cancellable_cancel, - cancellable); - g_object_weak_ref (G_OBJECT (session), - (GWeakNotify) - g_object_unref, - cancellable); - g_object_weak_ref (G_OBJECT (session), - (GWeakNotify) - g_free, - source_tag); - } - - g_free (username); -} - -static void -on_session_client_disconnected (GdmSession *session, - GCredentials *credentials, - GPid pid_of_client, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: client disconnected"); -} - -static void -on_session_cancelled (GdmSession *session, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: Session was cancelled"); - queue_greeter_reset (slave); -} - -static void -touch_marker_file (GdmSimpleSlave *slave) -{ - int fd; - - fd = g_creat (GDM_RAN_ONCE_MARKER_FILE, 0644); - - if (fd < 0 && errno != EEXIST) { - g_warning ("could not create %s to mark run, this may cause auto login " - "to repeat: %m", GDM_RAN_ONCE_MARKER_FILE); - return; - } - - fsync (fd); - close (fd); -} - -static void -create_new_session (GdmSimpleSlave *slave) -{ - gboolean display_is_local; - char *display_name; - char *display_hostname; - char *display_device; - char *display_seat_id; - char *display_x11_authority_file; - GdmSession *greeter_session; - uid_t greeter_uid; - - g_debug ("GdmSimpleSlave: Creating new session"); - - if (slave->priv->greeter_environment != NULL) { - greeter_session = gdm_launch_environment_get_session (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment)); - greeter_uid = gdm_session_get_allowed_user (greeter_session); - } else { - greeter_uid = 0; - } - - g_object_get (slave, - "display-name", &display_name, - "display-hostname", &display_hostname, - "display-is-local", &display_is_local, - "display-x11-authority-file", &display_x11_authority_file, - "display-seat-id", &display_seat_id, - NULL); - - display_device = NULL; - if (slave->priv->server != NULL) { - display_device = gdm_server_get_display_device (slave->priv->server); - } - - slave->priv->session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN, - greeter_uid, - display_name, - display_hostname, - display_device, - display_seat_id, - display_x11_authority_file, - display_is_local, - NULL); - - g_free (display_name); - g_free (display_device); - g_free (display_hostname); - - g_signal_connect (slave->priv->session, - "reauthentication-started", - G_CALLBACK (on_session_reauthentication_started), - slave); - g_signal_connect (slave->priv->session, - "reauthenticated", - G_CALLBACK (on_session_reauthenticated), - slave); - g_signal_connect (slave->priv->session, - "client-ready-for-session-to-start", - G_CALLBACK (on_session_client_ready_for_session_to_start), - slave); - g_signal_connect (slave->priv->session, - "client-connected", - G_CALLBACK (on_session_client_connected), - slave); - g_signal_connect (slave->priv->session, - "client-disconnected", - G_CALLBACK (on_session_client_disconnected), - slave); - g_signal_connect (slave->priv->session, - "cancelled", - G_CALLBACK (on_session_cancelled), - slave); - g_signal_connect (slave->priv->session, - "conversation-started", - G_CALLBACK (on_session_conversation_started), - slave); - g_signal_connect (slave->priv->session, - "conversation-stopped", - G_CALLBACK (on_session_conversation_stopped), - slave); - g_signal_connect (slave->priv->session, - "session-opened", - G_CALLBACK (on_session_opened), - slave); - g_signal_connect (slave->priv->session, - "session-started", - G_CALLBACK (on_session_started), - slave); - g_signal_connect (slave->priv->session, - "session-exited", - G_CALLBACK (on_session_exited), - slave); - g_signal_connect (slave->priv->session, - "session-died", - G_CALLBACK (on_session_died), - slave); - - start_autologin_conversation_if_necessary (slave); - - touch_marker_file (slave); -} - -static void on_greeter_environment_session_opened (GdmLaunchEnvironment *greeter_environment, GdmSimpleSlave *slave) { @@ -947,11 +313,7 @@ on_greeter_environment_session_stopped (GdmLaunchEnvironment *greeter_environmen GdmSimpleSlave *slave) { g_debug ("GdmSimpleSlave: Greeter stopped"); - if (slave->priv->start_session_service_name == NULL) { - gdm_slave_stop (GDM_SLAVE (slave)); - } else { - start_session (slave); - } + gdm_slave_stop (GDM_SLAVE (slave)); g_object_unref (slave->priv->greeter_environment); slave->priv->greeter_environment = NULL; @@ -963,9 +325,7 @@ on_greeter_environment_session_exited (GdmLaunchEnvironment *greeter_environm GdmSimpleSlave *slave) { g_debug ("GdmSimpleSlave: Greeter exited: %d", code); - if (slave->priv->start_session_service_name == NULL) { - gdm_slave_stop (GDM_SLAVE (slave)); - } + gdm_slave_stop (GDM_SLAVE (slave)); } static void @@ -974,9 +334,7 @@ on_greeter_environment_session_died (GdmLaunchEnvironment *greeter_environmen GdmSimpleSlave *slave) { g_debug ("GdmSimpleSlave: Greeter died: %d", signal); - if (slave->priv->start_session_service_name == NULL) { - gdm_slave_stop (GDM_SLAVE (slave)); - } + gdm_slave_stop (GDM_SLAVE (slave)); } #ifdef WITH_PLYMOUTH @@ -1278,14 +636,58 @@ wants_initial_setup (GdmSimpleSlave *slave) } static void -setup_session (GdmSimpleSlave *slave) +gdm_simple_slave_set_up_greeter_session (GdmSlave *slave, + char **username) +{ + GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); + + if (wants_initial_setup (self)) { + *username = g_strdup (INITIAL_SETUP_USERNAME); + } else if (wants_autologin (self)) { + *username = g_strdup ("root"); + } else { + *username = g_strdup (GDM_USERNAME); + } +} + +static void +gdm_simple_slave_stop_greeter_session (GdmSlave *slave) +{ + GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); + + if (self->priv->greeter_environment != NULL) { + g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, + G_CALLBACK (on_greeter_environment_session_opened), + self); + g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, + G_CALLBACK (on_greeter_environment_session_started), + self); + g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, + G_CALLBACK (on_greeter_environment_session_stopped), + self); + g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, + G_CALLBACK (on_greeter_environment_session_exited), + self); + g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, + G_CALLBACK (on_greeter_environment_session_died), + self); + gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (self->priv->greeter_environment)); + g_clear_object (&self->priv->greeter_environment); + } + + if (GDM_SIMPLE_SLAVE (slave)->priv->doing_initial_setup) { + chown_initial_setup_home_dir (); + } +} + +static void +gdm_simple_slave_start_greeter_session (GdmSlave *slave) { - if (wants_initial_setup (slave)) { - start_initial_setup (slave); - } else if (!wants_autologin (slave)) { - start_greeter (slave); + if (wants_initial_setup (GDM_SIMPLE_SLAVE (slave))) { + start_initial_setup (GDM_SIMPLE_SLAVE (slave)); + } else if (!wants_autologin (GDM_SIMPLE_SLAVE (slave))) { + start_greeter (GDM_SIMPLE_SLAVE (slave)); } - create_new_session (slave); } static gboolean @@ -1298,7 +700,6 @@ idle_connect_to_display (GdmSimpleSlave *slave) res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave)); if (res) { setup_server (slave); - setup_session (slave); } else { if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) { g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts); @@ -1495,98 +896,6 @@ gdm_simple_slave_run (GdmSimpleSlave *slave) } static gboolean -gdm_simple_slave_open_session (GdmSlave *slave, - GPid pid_of_caller, - uid_t uid_of_caller, - const char **address, - GError **error) -{ - GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); - uid_t allowed_user; - - if (self->priv->session_is_running) { - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Can only be called before user is logged in")); - return FALSE; - } - - allowed_user = gdm_session_get_allowed_user (self->priv->session); - - if (uid_of_caller != allowed_user) { - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Caller not GDM")); - return FALSE; - } - - *address = gdm_session_get_server_address (self->priv->session); - return TRUE; -} - -static char * -gdm_simple_slave_open_reauthentication_channel_finish (GdmSlave *slave, - GAsyncResult *result, - GError **error) -{ - GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); - const char *address; - - g_return_val_if_fail (g_simple_async_result_is_valid (result, - G_OBJECT (self), - gdm_simple_slave_open_reauthentication_channel), NULL); - - address = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)); - - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) { - return NULL; - } - - return g_strdup (address); -} - -static void -gdm_simple_slave_open_reauthentication_channel (GdmSlave *slave, - const char *username, - GPid pid_of_caller, - uid_t uid_of_caller, - GAsyncReadyCallback callback, - gpointer user_data, - GCancellable *cancellable) -{ - GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); - GSimpleAsyncResult *result; - - result = g_simple_async_result_new (G_OBJECT (slave), - callback, - user_data, - gdm_simple_slave_open_reauthentication_channel); - - g_simple_async_result_set_check_cancellable (result, cancellable); - - if (!self->priv->session_is_running) { - g_simple_async_result_set_error (result, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("User not logged in")); - g_simple_async_result_complete_in_idle (result); - - } else { - g_hash_table_insert (self->priv->open_reauthentication_requests, - GINT_TO_POINTER (pid_of_caller), - g_object_ref (result)); - - gdm_session_start_reauthentication (self->priv->session, - pid_of_caller, - uid_of_caller); - } - - g_object_unref (result); -} - -static gboolean gdm_simple_slave_start (GdmSlave *slave) { GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->start (slave); @@ -1605,46 +914,7 @@ gdm_simple_slave_stop (GdmSlave *slave) GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave); - if (self->priv->greeter_environment != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (self->priv->greeter_environment), - G_CALLBACK (on_greeter_environment_session_opened), - self); - g_signal_handlers_disconnect_by_func (G_OBJECT (self->priv->greeter_environment), - G_CALLBACK (on_greeter_environment_session_started), - self); - g_signal_handlers_disconnect_by_func (G_OBJECT (self->priv->greeter_environment), - G_CALLBACK (on_greeter_environment_session_stopped), - self); - g_signal_handlers_disconnect_by_func (G_OBJECT (self->priv->greeter_environment), - G_CALLBACK (on_greeter_environment_session_exited), - self); - g_signal_handlers_disconnect_by_func (G_OBJECT (self->priv->greeter_environment), - G_CALLBACK (on_greeter_environment_session_died), - self); - gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (self->priv->greeter_environment)); - g_clear_object (&self->priv->greeter_environment); - } - - if (self->priv->start_session_id > 0) { - g_source_remove (self->priv->start_session_id); - self->priv->start_session_id = 0; - } - - g_clear_pointer (&self->priv->start_session_service_name, - (GDestroyNotify) g_free); - - if (self->priv->session_is_running) { -#ifdef HAVE_LOGINDEVPERM - gdm_simple_slave_revoke_console_permissions (self); -#endif - - self->priv->session_is_running = FALSE; - } - - if (self->priv->session != NULL) { - gdm_session_close (self->priv->session); - g_clear_object (&self->priv->session); - } + gdm_simple_slave_stop_greeter_session (slave); if (self->priv->server != NULL) { gdm_server_stop (self->priv->server); @@ -1666,9 +936,9 @@ gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass) slave_class->start = gdm_simple_slave_start; slave_class->stop = gdm_simple_slave_stop; - slave_class->open_session = gdm_simple_slave_open_session; - slave_class->open_reauthentication_channel = gdm_simple_slave_open_reauthentication_channel; - slave_class->open_reauthentication_channel_finish = gdm_simple_slave_open_reauthentication_channel_finish; + slave_class->set_up_greeter_session = gdm_simple_slave_set_up_greeter_session; + slave_class->start_greeter_session = gdm_simple_slave_start_greeter_session; + slave_class->stop_greeter_session = gdm_simple_slave_stop_greeter_session; g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate)); } @@ -1680,13 +950,6 @@ gdm_simple_slave_init (GdmSimpleSlave *slave) #ifdef HAVE_LOGINDEVPERM slave->priv->use_logindevperm = FALSE; #endif - - slave->priv->open_reauthentication_requests = g_hash_table_new_full (NULL, - NULL, - (GDestroyNotify) - NULL, - (GDestroyNotify) - g_object_unref); } static void @@ -1701,8 +964,6 @@ gdm_simple_slave_finalize (GObject *object) g_return_if_fail (slave->priv != NULL); - g_hash_table_unref (slave->priv->open_reauthentication_requests); - if (slave->priv->greeter_reset_id > 0) { g_source_remove (slave->priv->greeter_reset_id); slave->priv->greeter_reset_id = 0; @@ -1710,15 +971,3 @@ gdm_simple_slave_finalize (GObject *object) G_OBJECT_CLASS (gdm_simple_slave_parent_class)->finalize (object); } - -GdmSlave * -gdm_simple_slave_new (const char *id) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_SIMPLE_SLAVE, - "display-id", id, - NULL); - - return GDM_SLAVE (object); -} diff --git a/daemon/gdm-simple-slave.h b/daemon/gdm-simple-slave.h index f958a15b..376aedab 100644 --- a/daemon/gdm-simple-slave.h +++ b/daemon/gdm-simple-slave.h @@ -48,7 +48,6 @@ typedef struct } GdmSimpleSlaveClass; GType gdm_simple_slave_get_type (void); -GdmSlave * gdm_simple_slave_new (const char *id); G_END_DECLS diff --git a/daemon/gdm-slave-job.c b/daemon/gdm-slave-job.c deleted file mode 100644 index 58ac630c..00000000 --- a/daemon/gdm-slave-job.c +++ /dev/null @@ -1,478 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <errno.h> -#include <signal.h> - -#ifdef WITH_SYSTEMD -#include <systemd/sd-daemon.h> -#endif - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib/gstdio.h> -#include <glib-object.h> - -#include "gdm-common.h" - -#include "gdm-slave-job.h" - -#define GDM_SLAVE_JOB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE_JOB, GdmSlaveJobPrivate)) - -#define MAX_LOGS 5 - -struct GdmSlaveJobPrivate -{ - char *command; - char *log_path; - GPid pid; - guint child_watch_id; -}; - -enum { - PROP_0, - PROP_COMMAND, - PROP_LOG_PATH, -}; - -enum { - EXITED, - DIED, - LAST_SIGNAL -}; - -static guint signals [LAST_SIGNAL] = { 0, }; - -static void gdm_slave_job_class_init (GdmSlaveJobClass *klass); -static void gdm_slave_job_init (GdmSlaveJob *slave); -static void gdm_slave_job_finalize (GObject *object); - -G_DEFINE_TYPE (GdmSlaveJob, gdm_slave_job, G_TYPE_OBJECT) - -static void -child_watch (GPid pid, - int status, - GdmSlaveJob *slave) -{ - g_debug ("GdmSlaveJob: slave (pid:%d) done (%s:%d)", - (int) pid, - WIFEXITED (status) ? "status" - : WIFSIGNALED (status) ? "signal" - : "unknown", - WIFEXITED (status) ? WEXITSTATUS (status) - : WIFSIGNALED (status) ? WTERMSIG (status) - : -1); - - g_spawn_close_pid (slave->priv->pid); - slave->priv->pid = -1; - slave->priv->child_watch_id = 0; - - if (WIFEXITED (status)) { - int code = WEXITSTATUS (status); - g_signal_emit (slave, signals [EXITED], 0, code); - } else if (WIFSIGNALED (status)) { - int num = WTERMSIG (status); - g_signal_emit (slave, signals [DIED], 0, num); - } -} - -static void -rotate_logs (const char *path, - guint n_copies) -{ - int i; - - for (i = n_copies - 1; i > 0; i--) { - char *name_n; - char *name_n1; - - name_n = g_strdup_printf ("%s.%d", path, i); - if (i > 1) { - name_n1 = g_strdup_printf ("%s.%d", path, i - 1); - } else { - name_n1 = g_strdup (path); - } - - VE_IGNORE_EINTR (g_unlink (name_n)); - VE_IGNORE_EINTR (g_rename (name_n1, name_n)); - - g_free (name_n1); - g_free (name_n); - } - - VE_IGNORE_EINTR (g_unlink (path)); -} - -typedef struct { - const char *identifier; - const char *log_file; -} SpawnChildData; - -static void -spawn_child_setup (SpawnChildData *data) -{ -#ifdef WITH_SYSTEMD - if (sd_booted () > 0) { - return; - } -#endif - - if (data->log_file != NULL) { - int logfd; - - rotate_logs (data->log_file, MAX_LOGS); - - VE_IGNORE_EINTR (g_unlink (data->log_file)); - VE_IGNORE_EINTR (logfd = open (data->log_file, O_CREAT|O_APPEND|O_TRUNC|O_WRONLY|O_EXCL, 0644)); - - if (logfd != -1) { - VE_IGNORE_EINTR (dup2 (logfd, 1)); - VE_IGNORE_EINTR (dup2 (logfd, 2)); - close (logfd); - } - } -} - -static gboolean -spawn_command_line_async (const char *command_line, - const char *log_file, - char **env, - GPid *child_pid, - GError **error) -{ - char **argv; - GError *local_error; - gboolean ret; - gboolean res; - SpawnChildData data; - gboolean has_journald = FALSE; - - ret = FALSE; - - argv = NULL; - local_error = NULL; - if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) { - g_warning ("Could not parse command: %s", local_error->message); - g_propagate_error (error, local_error); - goto out; - } - - data.identifier = argv[0]; - -#ifdef WITH_SYSTEMD - if (sd_booted () > 0) { - has_journald = TRUE; - } -#endif - - if (has_journald) { - data.log_file = NULL; - } else { - data.log_file = log_file; - } - - local_error = NULL; - res = g_spawn_async (NULL, - argv, - env, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - (GSpawnChildSetupFunc)spawn_child_setup, - &data, - child_pid, - &local_error); - - if (! res) { - g_warning ("Could not spawn command: %s", local_error->message); - g_propagate_error (error, local_error); - goto out; - } - - ret = TRUE; - out: - g_strfreev (argv); - - return ret; -} - -static void -clear_child_watch (GdmSlaveJob *slave) -{ - slave->priv->child_watch_id = 0; - g_object_unref (slave); -} - -static gboolean -spawn_slave (GdmSlaveJob *slave) -{ - gboolean result; - GError *error; - - g_debug ("GdmSlaveJob: Running command: %s", slave->priv->command); - - error = NULL; - result = spawn_command_line_async (slave->priv->command, - slave->priv->log_path, - NULL, - &slave->priv->pid, - &error); - if (! result) { - g_warning ("Could not start command '%s': %s", slave->priv->command, error->message); - g_error_free (error); - goto out; - } - - g_debug ("GdmSlaveJob: Started slave with pid %d", slave->priv->pid); - - slave->priv->child_watch_id = g_child_watch_add_full (G_PRIORITY_DEFAULT, - slave->priv->pid, - (GChildWatchFunc)child_watch, - g_object_ref (slave), - (GDestroyNotify) - clear_child_watch); - - result = TRUE; - - out: - - return result; -} - -static void -kill_slave (GdmSlaveJob *slave) -{ - int res; - - if (slave->priv->pid <= 1) { - return; - } - - res = gdm_signal_pid (slave->priv->pid, SIGTERM); - if (res < 0) { - g_warning ("Unable to kill slave process"); - } else { - int exit_status; - - exit_status = gdm_wait_on_pid (slave->priv->pid); - - g_debug ("GdmSlaveJob: slave died with exit status %d", exit_status); - - g_spawn_close_pid (slave->priv->pid); - slave->priv->pid = 0; - } -} - -gboolean -gdm_slave_job_start (GdmSlaveJob *slave) -{ - gdm_slave_job_stop (slave); - - spawn_slave (slave); - - return TRUE; -} - -gboolean -gdm_slave_job_stop (GdmSlaveJob *slave) -{ - g_debug ("GdmSlaveJob: Killing slave"); - - if (slave->priv->child_watch_id > 0) { - g_source_remove (slave->priv->child_watch_id); - slave->priv->child_watch_id = 0; - } - - kill_slave (slave); - - return TRUE; -} - -void -gdm_slave_job_set_command (GdmSlaveJob *slave, - const char *command) -{ - g_free (slave->priv->command); - slave->priv->command = g_strdup (command); -} - -void -gdm_slave_job_set_log_path (GdmSlaveJob *slave, - const char *path) -{ - g_free (slave->priv->log_path); - slave->priv->log_path = g_strdup (path); -} - -static void -gdm_slave_job_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmSlaveJob *self; - - self = GDM_SLAVE_JOB (object); - - switch (prop_id) { - case PROP_COMMAND: - gdm_slave_job_set_command (self, g_value_get_string (value)); - break; - case PROP_LOG_PATH: - gdm_slave_job_set_log_path (self, g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_slave_job_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdmSlaveJob *self; - - self = GDM_SLAVE_JOB (object); - - switch (prop_id) { - case PROP_COMMAND: - g_value_set_string (value, self->priv->command); - break; - case PROP_LOG_PATH: - g_value_set_string (value, self->priv->log_path); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_slave_job_dispose (GObject *object) -{ - GdmSlaveJob *slave; - - slave = GDM_SLAVE_JOB (object); - - g_debug ("GdmSlaveJob: Disposing slave job"); - gdm_slave_job_stop (slave); - - G_OBJECT_CLASS (gdm_slave_job_parent_class)->dispose (object); -} - -static void -gdm_slave_job_class_init (GdmSlaveJobClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_slave_job_get_property; - object_class->set_property = gdm_slave_job_set_property; - object_class->dispose = gdm_slave_job_dispose; - object_class->finalize = gdm_slave_job_finalize; - - g_type_class_add_private (klass, sizeof (GdmSlaveJobPrivate)); - - g_object_class_install_property (object_class, - PROP_COMMAND, - g_param_spec_string ("command", - "command", - "command", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_LOG_PATH, - g_param_spec_string ("log-path", - "log path", - "log path", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - signals [EXITED] = - g_signal_new ("exited", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSlaveJobClass, 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 (GdmSlaveJobClass, died), - NULL, - NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); -} - -static void -gdm_slave_job_init (GdmSlaveJob *slave) -{ - - slave->priv = GDM_SLAVE_JOB_GET_PRIVATE (slave); - - slave->priv->pid = -1; -} - -static void -gdm_slave_job_finalize (GObject *object) -{ - GdmSlaveJob *slave; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_SLAVE_JOB (object)); - - slave = GDM_SLAVE_JOB (object); - - g_return_if_fail (slave->priv != NULL); - - g_free (slave->priv->command); - g_free (slave->priv->log_path); - - G_OBJECT_CLASS (gdm_slave_job_parent_class)->finalize (object); -} - -GdmSlaveJob * -gdm_slave_job_new (void) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_SLAVE_JOB, - NULL); - - return GDM_SLAVE_JOB (object); -} diff --git a/daemon/gdm-slave-job.h b/daemon/gdm-slave-job.h deleted file mode 100644 index 65bf00d0..00000000 --- a/daemon/gdm-slave-job.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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. - * - */ - - -#ifndef __GDM_SLAVE_JOB_H -#define __GDM_SLAVE_JOB_H - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define GDM_TYPE_SLAVE_JOB (gdm_slave_job_get_type ()) -#define GDM_SLAVE_JOB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SLAVE_JOB, GdmSlaveJob)) -#define GDM_SLAVE_JOB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SLAVE_JOB, GdmSlaveJobClass)) -#define GDM_IS_SLAVE_JOB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SLAVE_JOB)) -#define GDM_IS_SLAVE_JOB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SLAVE_JOB)) -#define GDM_SLAVE_JOB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SLAVE_JOB, GdmSlaveJobClass)) - -typedef struct GdmSlaveJobPrivate GdmSlaveJobPrivate; - -typedef struct -{ - GObject parent; - GdmSlaveJobPrivate *priv; -} GdmSlaveJob; - -typedef struct -{ - GObjectClass parent_class; - void (* exited) (GdmSlaveJob *job, - int exit_code); - - void (* died) (GdmSlaveJob *job, - int signal_number); -} GdmSlaveJobClass; - -GType gdm_slave_job_get_type (void); -GdmSlaveJob * gdm_slave_job_new (void); -void gdm_slave_job_set_command (GdmSlaveJob *slave, - const char *command); -void gdm_slave_job_set_log_path (GdmSlaveJob *slave, - const char *path); -gboolean gdm_slave_job_start (GdmSlaveJob *slave); -gboolean gdm_slave_job_stop (GdmSlaveJob *slave); - -G_END_DECLS - -#endif /* __GDM_SLAVE_JOB_H */ diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c index b3824515..1afe48e7 100644 --- a/daemon/gdm-slave.c +++ b/daemon/gdm-slave.c @@ -51,27 +51,13 @@ #include "gdm-xerrors.h" #include "gdm-slave.h" -#include "gdm-slave-glue.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)) -#define CK_NAME "org.freedesktop.ConsoleKit" -#define CK_PATH "/org/freedesktop/ConsoleKit" -#define CK_INTERFACE "org.freedesktop.ConsoleKit" - -#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" -#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" -#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" -#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" - -#define GDM_DBUS_NAME "org.gnome.DisplayManager" -#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display" - -#define GDM_SLAVE_PATH "/org/gnome/DisplayManager/Slave" - struct GdmSlavePrivate { GPid pid; @@ -82,8 +68,9 @@ struct GdmSlavePrivate char *session_id; + GdmDisplay *display; + /* cached display values */ - char *display_id; char *display_name; int display_number; char *display_hostname; @@ -93,16 +80,12 @@ struct GdmSlavePrivate char *windowpath; GBytes *display_x11_cookie; gboolean display_is_initial; - - GdmDBusDisplay *display_proxy; - GDBusConnection *connection; - GdmDBusSlave *skeleton; }; enum { PROP_0, PROP_SESSION_ID, - PROP_DISPLAY_ID, + PROP_DISPLAY, PROP_DISPLAY_NAME, PROP_DISPLAY_NUMBER, PROP_DISPLAY_HOSTNAME, @@ -113,6 +96,7 @@ enum { }; enum { + STARTED, STOPPED, LAST_SIGNAL }; @@ -320,91 +304,26 @@ gdm_slave_connect_to_x11_display (GdmSlave *slave) ret = TRUE; } - return ret; -} - -static gboolean -gdm_slave_set_slave_bus_name (GdmSlave *slave) -{ - gboolean res; - GError *error; - const char *name; - - name = g_dbus_connection_get_unique_name (slave->priv->connection); - - error = NULL; - res = gdm_dbus_display_call_set_slave_bus_name_sync (slave->priv->display_proxy, - name, - NULL, - &error); - if (! res) { - g_warning ("Failed to set slave bus name on parent: %s", error->message); - g_error_free (error); + if (ret) { + g_signal_emit (slave, signals [STARTED], 0); } - return res; + return ret; } static gboolean gdm_slave_real_start (GdmSlave *slave) { gboolean res; - char *id = NULL; GError *error; - GVariant *x11_cookie; - const char *x11_cookie_bytes; + const char *x11_cookie; gsize x11_cookie_size; g_debug ("GdmSlave: Starting slave"); - g_assert (slave->priv->display_proxy == NULL); - - if (! g_variant_is_object_path (slave->priv->display_id)) { - g_warning ("Display ID isn't valid"); - return FALSE; - } - - g_debug ("GdmSlave: Creating proxy for %s", slave->priv->display_id); - error = NULL; - slave->priv->display_proxy = GDM_DBUS_DISPLAY (gdm_dbus_display_proxy_new_sync (slave->priv->connection, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, - GDM_DBUS_NAME, - slave->priv->display_id, - NULL, - &error)); - - if (slave->priv->display_proxy == NULL) { - g_warning ("Failed to create display proxy %s: %s", slave->priv->display_id, error->message); - g_error_free (error); - return FALSE; - } - - error = NULL; - res = gdm_dbus_display_call_get_id_sync (slave->priv->display_proxy, - &id, - NULL, - &error); - if (! res || !id) { - g_warning ("Failed to get display ID %s: %s", slave->priv->display_id, error->message); - g_error_free (error); - return FALSE; - } - - g_debug ("GdmSlave: Got display ID: %s", id); - - if (strcmp (id, slave->priv->display_id) != 0) { - g_warning ("Display ID doesn't match"); - return FALSE; - } - - gdm_slave_set_slave_bus_name (slave); - /* cache some values up front */ error = NULL; - res = gdm_dbus_display_call_is_local_sync (slave->priv->display_proxy, - &slave->priv->display_is_local, - NULL, - &error); + 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); g_error_free (error); @@ -412,10 +331,7 @@ gdm_slave_real_start (GdmSlave *slave) } error = NULL; - res = gdm_dbus_display_call_get_x11_display_name_sync (slave->priv->display_proxy, - &slave->priv->display_name, - NULL, - &error); + res = gdm_display_get_x11_display_name (slave->priv->display, &slave->priv->display_name, &error); if (! res) { g_warning ("Failed to get value: %s", error->message); g_error_free (error); @@ -423,10 +339,7 @@ gdm_slave_real_start (GdmSlave *slave) } error = NULL; - res = gdm_dbus_display_call_get_x11_display_number_sync (slave->priv->display_proxy, - &slave->priv->display_number, - NULL, - &error); + res = gdm_display_get_x11_display_number (slave->priv->display, &slave->priv->display_number, &error); if (! res) { g_warning ("Failed to get value: %s", error->message); g_error_free (error); @@ -434,10 +347,7 @@ gdm_slave_real_start (GdmSlave *slave) } error = NULL; - res = gdm_dbus_display_call_get_remote_hostname_sync (slave->priv->display_proxy, - &slave->priv->display_hostname, - NULL, - &error); + res = gdm_display_get_remote_hostname (slave->priv->display, &slave->priv->display_hostname, &error); if (! res) { g_warning ("Failed to get value: %s", error->message); g_error_free (error); @@ -445,33 +355,20 @@ gdm_slave_real_start (GdmSlave *slave) } error = NULL; - res = gdm_dbus_display_call_get_x11_cookie_sync (slave->priv->display_proxy, - &x11_cookie, - NULL, - &error); + res = gdm_display_get_x11_cookie (slave->priv->display, &x11_cookie, &x11_cookie_size, &error); if (! res) { g_warning ("Failed to get value: %s", error->message); g_error_free (error); return FALSE; } - x11_cookie_bytes = g_variant_get_fixed_array (x11_cookie, - &x11_cookie_size, - sizeof (char)); - - if (x11_cookie_bytes != NULL && x11_cookie_size > 0) { + if (x11_cookie != NULL && x11_cookie_size > 0) { g_bytes_unref (slave->priv->display_x11_cookie); - slave->priv->display_x11_cookie = g_bytes_new (x11_cookie_bytes, - x11_cookie_size); + slave->priv->display_x11_cookie = g_bytes_new (x11_cookie, x11_cookie_size); } - g_variant_unref (x11_cookie); - error = NULL; - res = gdm_dbus_display_call_get_x11_authority_file_sync (slave->priv->display_proxy, - &slave->priv->display_x11_authority_file, - NULL, - &error); + res = gdm_display_get_x11_authority_file (slave->priv->display, &slave->priv->display_x11_authority_file, &error); if (! res) { g_warning ("Failed to get value: %s", error->message); g_error_free (error); @@ -479,10 +376,7 @@ gdm_slave_real_start (GdmSlave *slave) } error = NULL; - res = gdm_dbus_display_call_get_seat_id_sync (slave->priv->display_proxy, - &slave->priv->display_seat_id, - NULL, - &error); + 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); @@ -490,10 +384,7 @@ gdm_slave_real_start (GdmSlave *slave) } error = NULL; - res = gdm_dbus_display_call_is_initial_sync (slave->priv->display_proxy, - &slave->priv->display_is_initial, - NULL, - &error); + 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); @@ -508,7 +399,7 @@ gdm_slave_real_stop (GdmSlave *slave) { g_debug ("GdmSlave: Stopping slave"); - g_clear_object (&slave->priv->display_proxy); + g_clear_object (&slave->priv->display); return TRUE; } @@ -568,11 +459,10 @@ gdm_slave_add_user_authorization (GdmSlave *slave, g_debug ("GdmSlave: Requesting user authorization"); error = NULL; - res = gdm_dbus_display_call_add_user_authorization_sync (slave->priv->display_proxy, - username, - &filename, - NULL, - &error); + res = gdm_display_add_user_authorization (slave->priv->display, + username, + &filename, + &error); if (! res) { g_warning ("Failed to add user authorization: %s", error->message); @@ -687,7 +577,6 @@ gdm_slave_parse_enriched_login (GdmSlave *slave, } out: - return parsed_username; } @@ -711,12 +600,11 @@ gdm_slave_get_timed_login_details (GdmSlave *slave, g_debug ("GdmSlave: Requesting timed login details"); error = NULL; - res = gdm_dbus_display_call_get_timed_login_details_sync (slave->priv->display_proxy, - &enabled, - &username, - &delay, - NULL, - &error); + res = gdm_display_get_timed_login_details (slave->priv->display, + &enabled, + &username, + &delay, + &error); if (! res) { g_warning ("Failed to get timed login details: %s", error->message); g_error_free (error); @@ -764,620 +652,6 @@ gdm_slave_get_timed_login_details (GdmSlave *slave, return res; } -static gboolean -_get_uid_and_gid_for_user (const char *username, - uid_t *uid, - gid_t *gid) -{ - struct passwd *passwd_entry; - - g_assert (username != NULL); - - errno = 0; - gdm_get_pwent_for_name (username, &passwd_entry); - - if (passwd_entry == NULL) { - return FALSE; - } - - if (uid != NULL) { - *uid = passwd_entry->pw_uid; - } - - if (gid != NULL) { - *gid = passwd_entry->pw_gid; - } - - return TRUE; -} - -#ifdef WITH_CONSOLE_KIT - -static gboolean -x11_session_is_on_seat (GdmSlave *slave, - const char *session_id, - const char *seat_id) -{ - GError *error = NULL; - GVariant *reply; - char *sid; - gboolean ret; - char *x11_display_device; - char *x11_display; - - ret = FALSE; - sid = NULL; - x11_display = NULL; - x11_display_device = NULL; - - if (seat_id == NULL || seat_id[0] == '\0' || session_id == NULL || session_id[0] == '\0') { - return FALSE; - } - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - session_id, - CK_SESSION_INTERFACE, - "GetSeatId", - NULL, /* parameters */ - G_VARIANT_TYPE ("(o)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("Failed to identify the current seat: %s", error->message); - g_error_free (error); - return FALSE; - } - - g_variant_get (reply, "(o)", &sid); - g_variant_unref (reply); - - if (sid == NULL || sid[0] == '\0' || strcmp (sid, seat_id) != 0) { - g_debug ("GdmSlave: session not on current seat: %s", seat_id); - goto out; - } - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - session_id, - CK_SESSION_INTERFACE, - "GetX11Display", - NULL, /* parameters */ - G_VARIANT_TYPE ("(s)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_error_free (error); - goto out; - } - - g_variant_get (reply, "(s)", &x11_display); - g_variant_unref (reply); - - /* ignore tty sessions */ - if (x11_display == NULL || x11_display[0] == '\0') { - goto out; - } - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - session_id, - CK_SESSION_INTERFACE, - "GetX11DisplayDevice", - NULL, /* parameters */ - G_VARIANT_TYPE ("(s)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_error_free (error); - goto out; - } - - g_variant_get (reply, "(s)", &x11_display_device); - g_variant_unref (reply); - - if (x11_display_device == NULL || x11_display_device[0] == '\0') { - goto out; - } - - ret = TRUE; - out: - g_free (x11_display_device); - g_free (x11_display); - g_free (sid); - - return ret; -} - -#endif - -#ifdef WITH_SYSTEMD -static char* -gdm_slave_get_primary_session_id_for_user_from_systemd (GdmSlave *slave, - const char *username) -{ - int res, i; - char **sessions; - uid_t uid; - char *primary_ssid; - gboolean got_primary_ssid; - - primary_ssid = NULL; - got_primary_ssid = FALSE; - - res = sd_seat_can_multi_session (slave->priv->display_seat_id); - if (res < 0) { - g_warning ("GdmSlave: Failed to determine whether seat is multi-session capable: %s", strerror (-res)); - return NULL; - } else if (res == 0) { - g_debug ("GdmSlave: seat is unable to activate sessions"); - return NULL; - } - - if (! _get_uid_and_gid_for_user (username, &uid, NULL)) { - g_debug ("GdmSlave: unable to determine uid for user: %s", username); - return NULL; - } - - res = sd_seat_get_sessions (slave->priv->display_seat_id, &sessions, NULL, NULL); - if (res < 0) { - g_warning ("GdmSlave: Failed to get sessions on seat: %s", strerror (-res)); - return NULL; - } - - if (sessions == NULL) { - g_debug ("GdmSlave: seat has no active sessions"); - return NULL; - } - - for (i = 0; sessions[i] != NULL; i++) { - char *type; - char *state; - gboolean is_closing; - gboolean is_active; - gboolean is_x11; - uid_t other; - - res = sd_session_get_type (sessions[i], &type); - - if (res < 0) { - g_warning ("GdmSlave: could not fetch type of session '%s': %s", - sessions[i], strerror (-res)); - continue; - } - - is_x11 = g_strcmp0 (type, "x11") == 0; - free (type); - - /* Only migrate to graphical sessions - */ - if (!is_x11) { - continue; - } - - /* Always give preference to non-active sessions, - * so we migrate when we can and don't when we can't - */ - res = sd_session_get_state (sessions[i], &state); - if (res < 0) { - g_warning ("GdmSlave: could not fetch state of session '%s': %s", - sessions[i], strerror (-res)); - continue; - } - - is_closing = g_strcmp0 (state, "closing") == 0; - is_active = g_strcmp0 (state, "active") == 0; - free (state); - - /* Ignore closing sessions - */ - if (is_closing) { - continue; - } - - res = sd_session_get_uid (sessions[i], &other); - if (res == 0 && other == uid && !got_primary_ssid) { - g_free (primary_ssid); - primary_ssid = g_strdup (sessions[i]); - - if (!is_active) { - got_primary_ssid = TRUE; - } - } - free (sessions[i]); - } - - free (sessions); - return primary_ssid; -} -#endif - -#ifdef WITH_CONSOLE_KIT -static char * -gdm_slave_get_primary_session_id_for_user_from_ck (GdmSlave *slave, - const char *username) -{ - gboolean can_activate_sessions; - GError *error; - const char **sessions; - int i; - char *primary_ssid; - uid_t uid; - GVariant *reply; - - error = NULL; - primary_ssid = NULL; - - g_debug ("GdmSlave: getting proxy for seat: %s", slave->priv->display_seat_id); - g_debug ("GdmSlave: checking if seat can activate sessions"); - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - slave->priv->display_seat_id, - CK_SEAT_INTERFACE, - "CanActivateSessions", - NULL, /* parameters */ - G_VARIANT_TYPE ("(b)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_warning ("unable to determine if seat can activate sessions: %s", error->message); - g_error_free (error); - return NULL; - } - - g_variant_get (reply, "(b)", &can_activate_sessions); - g_variant_unref (reply); - - if (! can_activate_sessions) { - g_debug ("GdmSlave: seat is unable to activate sessions"); - return NULL; - } - - if (! _get_uid_and_gid_for_user (username, &uid, NULL)) { - g_debug ("GdmSlave: unable to determine uid for user: %s", username); - return NULL; - } - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "GetSessionsForUnixUser", - g_variant_new ("(u)", uid), - G_VARIANT_TYPE ("(ao)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - - if (reply == NULL) { - g_warning ("unable to determine sessions for user: %s", error->message); - g_error_free (error); - return NULL; - } - - g_variant_get_child (reply, 0, "^a&o", &sessions); - for (i = 0; sessions[i] != NULL; i++) { - if (x11_session_is_on_seat (slave, sessions[i], slave->priv->display_seat_id)) { - primary_ssid = g_strdup (sessions[i]); - break; - } - } - - g_free (sessions); - g_variant_unref (reply); - return primary_ssid; -} -#endif - -char * -gdm_slave_get_primary_session_id_for_user (GdmSlave *slave, - const char *username) -{ - - if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') { - g_debug ("GdmSlave: display seat ID is not set; can't switch sessions"); - return NULL; - } - -#ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - return gdm_slave_get_primary_session_id_for_user_from_systemd (slave, username); - } -#endif - -#ifdef WITH_CONSOLE_KIT - return gdm_slave_get_primary_session_id_for_user_from_ck (slave, username); -#else - return NULL; -#endif -} - -#ifdef WITH_SYSTEMD -static gboolean -activate_session_id_for_systemd (GdmSlave *slave, - const char *seat_id, - const char *session_id) -{ - GError *error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (slave->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 ("GdmSlave: 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; -} -#endif - -#ifdef WITH_CONSOLE_KIT -static gboolean -activate_session_id_for_ck (GdmSlave *slave, - const char *seat_id, - const char *session_id) -{ - GError *error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - seat_id, - "org.freedesktop.ConsoleKit.Seat", - "ActivateSession", - g_variant_new ("(o)", session_id), - NULL, /* expected reply */ - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmSlave: ConsoleKit %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; -} -#endif - -static gboolean -activate_session_id (GdmSlave *slave, - const char *seat_id, - const char *session_id) -{ - -#ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - return activate_session_id_for_systemd (slave, seat_id, session_id); - } -#endif - -#ifdef WITH_CONSOLE_KIT - return activate_session_id_for_ck (slave, seat_id, session_id); -#else - return FALSE; -#endif -} - -#ifdef WITH_CONSOLE_KIT -static gboolean -ck_session_is_active (GdmSlave *slave, - const char *seat_id, - const char *session_id) -{ - GError *error = NULL; - GVariant *reply; - gboolean is_active; - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - session_id, - "org.freedesktop.ConsoleKit.Session", - "IsActive", - NULL, - G_VARIANT_TYPE ("(b)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmSlave: ConsoleKit IsActive %s raised:\n %s\n\n", - g_dbus_error_get_remote_error (error), error->message); - g_error_free (error); - return FALSE; - } - - g_variant_get (reply, "(b)", &is_active); - g_variant_unref (reply); - - return is_active; -} -#endif - -static gboolean -session_is_active (GdmSlave *slave, - const char *seat_id, - const char *session_id) -{ -#ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - return sd_session_is_active (session_id) > 0; - } -#endif - -#ifdef WITH_CONSOLE_KIT - return ck_session_is_active (slave, seat_id, session_id); -#else - return FALSE; -#endif -} - -#ifdef WITH_SYSTEMD -static gboolean -session_unlock_for_systemd (GdmSlave *slave, - const char *ssid) -{ - GError *error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (slave->priv->connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "UnlockSession", - g_variant_new ("(s)", ssid), - NULL, /* expected reply */ - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmSlave: logind 'UnlockSession' %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; -} -#endif - -#ifdef WITH_CONSOLE_KIT -static gboolean -session_unlock_for_ck (GdmSlave *slave, - const char *ssid) -{ - GError *error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (slave->priv->connection, - CK_NAME, - ssid, - CK_SESSION_INTERFACE, - "Unlock", - NULL, /* parameters */ - NULL, /* expected reply */ - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmSlave: ConsoleKit %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; -} -#endif - -static gboolean -session_unlock (GdmSlave *slave, - const char *ssid) -{ - - g_debug ("Unlocking session %s", ssid); - -#ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - return session_unlock_for_systemd (slave, ssid); - } -#endif - -#ifdef WITH_CONSOLE_KIT - return session_unlock_for_ck (slave, ssid); -#else - return TRUE; -#endif -} - -gboolean -gdm_slave_switch_to_user_session (GdmSlave *slave, - const char *username, - const char *session_id, - gboolean fail_if_already_switched) -{ - gboolean res; - gboolean ret; - gboolean session_already_switched; - char *ssid_to_activate; - - ret = FALSE; - - if (session_id != NULL) { - ssid_to_activate = g_strdup (session_id); - } else { - ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username); - if (ssid_to_activate == NULL) { - g_debug ("GdmSlave: unable to determine session to activate"); - goto out; - } - } - - session_already_switched = session_is_active (slave, slave->priv->display_seat_id, ssid_to_activate); - - g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate); - - if (session_already_switched && fail_if_already_switched) { - g_debug ("GdmSlave: unable to activate session since it's already active: %s", ssid_to_activate); - goto out; - } - - if (!session_already_switched) { - res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate); - if (! res) { - g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate); - goto out; - } - } - - res = session_unlock (slave, ssid_to_activate); - if (!res) { - /* this isn't fatal */ - g_debug ("GdmSlave: unable to unlock session: %s", ssid_to_activate); - } - - ret = TRUE; - - out: - g_free (ssid_to_activate); - - return ret; -} - static void _gdm_slave_set_session_id (GdmSlave *slave, const char *id) @@ -1387,14 +661,6 @@ _gdm_slave_set_session_id (GdmSlave *slave, } static void -_gdm_slave_set_display_id (GdmSlave *slave, - const char *id) -{ - g_free (slave->priv->display_id); - slave->priv->display_id = g_strdup (id); -} - -static void gdm_slave_set_property (GObject *object, guint prop_id, const GValue *value, @@ -1408,8 +674,8 @@ gdm_slave_set_property (GObject *object, case PROP_SESSION_ID: _gdm_slave_set_session_id (self, g_value_get_string (value)); break; - case PROP_DISPLAY_ID: - _gdm_slave_set_display_id (self, g_value_get_string (value)); + case PROP_DISPLAY: + self->priv->display = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1431,8 +697,8 @@ gdm_slave_get_property (GObject *object, case PROP_SESSION_ID: g_value_set_string (value, self->priv->session_id); break; - case PROP_DISPLAY_ID: - g_value_set_string (value, self->priv->display_id); + case PROP_DISPLAY: + g_value_set_object (value, self->priv->display); break; case PROP_DISPLAY_NAME: g_value_set_string (value, self->priv->display_name); @@ -1461,156 +727,23 @@ gdm_slave_get_property (GObject *object, } } -static gboolean -handle_open_session (GdmDBusSlave *skeleton, - GDBusMethodInvocation *invocation, - int pid_of_caller, - int uid_of_caller, - GdmSlave *slave) -{ - GError *error; - GdmSlaveClass *slave_class; - const char *address; - - slave_class = GDM_SLAVE_GET_CLASS (slave); - if (slave_class->open_session == NULL) { - g_dbus_method_invocation_return_dbus_error (invocation, - "org.gnome.DisplayManager.Slave.Unsupported", - "Connections to the slave are not supported by this slave"); - return TRUE; - } - - error = NULL; - address = NULL; - if (!slave_class->open_session (slave, - (GPid) pid_of_caller, - (uid_t) uid_of_caller, - &address, - &error)) { - g_dbus_method_invocation_return_gerror (invocation, error); - g_error_free (error); - return TRUE; - } - - gdm_dbus_slave_complete_open_session (skeleton, invocation, address); - - return TRUE; -} - -static void -on_reauthentication_channel_opened (GdmSlave *slave, - GAsyncResult *result, - GDBusMethodInvocation *invocation) -{ - GdmSlaveClass *slave_class; - GError *error; - char *address; - - slave_class = GDM_SLAVE_GET_CLASS (slave); - - g_assert (slave_class->open_reauthentication_channel_finish != NULL); - - error = NULL; - address = slave_class->open_reauthentication_channel_finish (slave, result, &error); - - if (address == NULL) { - g_dbus_method_invocation_return_gerror (invocation, error); - } else { - gdm_dbus_slave_complete_open_reauthentication_channel (slave->priv->skeleton, - invocation, - address); - } - - g_object_unref (invocation); -} - -static gboolean -handle_open_reauthentication_channel (GdmDBusSlave *skeleton, - GDBusMethodInvocation *invocation, - const char *username, - GPid pid_of_caller, - uid_t uid_of_caller, - GdmSlave *slave) +void +gdm_slave_set_up_greeter_session (GdmSlave *slave, + char **username) { - GdmSlaveClass *slave_class; - - slave_class = GDM_SLAVE_GET_CLASS (slave); - if (slave_class->open_reauthentication_channel == NULL) { - g_dbus_method_invocation_return_dbus_error (invocation, - "org.gnome.DisplayManager.Slave.Unsupported", - "Connections to the slave are not supported by this slave"); - return TRUE; - } - - slave_class->open_reauthentication_channel (slave, - username, - pid_of_caller, - uid_of_caller, - (GAsyncReadyCallback) - on_reauthentication_channel_opened, - g_object_ref (invocation), - NULL); - - return TRUE; + GDM_SLAVE_GET_CLASS (slave)->set_up_greeter_session (slave, username); } -static gboolean -register_slave (GdmSlave *slave) +void +gdm_slave_start_greeter_session (GdmSlave *slave) { - GError *error; - - error = NULL; - slave->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, - NULL, - &error); - if (slave->priv->connection == NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - exit (1); - } - - slave->priv->skeleton = GDM_DBUS_SLAVE (gdm_dbus_slave_skeleton_new ()); - - g_signal_connect (slave->priv->skeleton, - "handle-open-session", - G_CALLBACK (handle_open_session), - slave); - g_signal_connect (slave->priv->skeleton, - "handle-open-reauthentication-channel", - G_CALLBACK (handle_open_reauthentication_channel), - slave); - - g_object_bind_property (G_OBJECT (slave), - "session-id", - G_OBJECT (slave->priv->skeleton), - "session-id", - G_BINDING_DEFAULT); - - gdm_slave_export_interface (slave, - G_DBUS_INTERFACE_SKELETON (slave->priv->skeleton)); - - return TRUE; + GDM_SLAVE_GET_CLASS (slave)->start_greeter_session (slave); } -static GObject * -gdm_slave_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) +void +gdm_slave_stop_greeter_session (GdmSlave *slave) { - GdmSlave *slave; - gboolean res; - - slave = GDM_SLAVE (G_OBJECT_CLASS (gdm_slave_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - g_debug ("GdmSlave: Registering"); - - res = register_slave (slave); - if (! res) { - g_warning ("Unable to register slave with system bus"); - } - - return G_OBJECT (slave); + GDM_SLAVE_GET_CLASS (slave)->stop_greeter_session (slave); } static void @@ -1620,7 +753,6 @@ gdm_slave_class_init (GdmSlaveClass *klass) object_class->get_property = gdm_slave_get_property; object_class->set_property = gdm_slave_set_property; - object_class->constructor = gdm_slave_constructor; object_class->finalize = gdm_slave_finalize; klass->start = gdm_slave_real_start; @@ -1636,11 +768,11 @@ gdm_slave_class_init (GdmSlaveClass *klass) NULL, G_PARAM_READWRITE)); g_object_class_install_property (object_class, - PROP_DISPLAY_ID, - g_param_spec_string ("display-id", + PROP_DISPLAY, + g_param_spec_object ("display", "id", "id", - NULL, + GDM_TYPE_DISPLAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_DISPLAY_NAME, @@ -1694,6 +826,17 @@ gdm_slave_class_init (GdmSlaveClass *klass) FALSE, G_PARAM_READABLE)); + signals [STARTED] = + g_signal_new ("started", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals [STOPPED] = g_signal_new ("stopped", G_TYPE_FROM_CLASS (object_class), @@ -1709,7 +852,6 @@ gdm_slave_class_init (GdmSlaveClass *klass) static void gdm_slave_init (GdmSlave *slave) { - slave->priv = GDM_SLAVE_GET_PRIVATE (slave); slave->priv->pid = -1; @@ -1727,7 +869,6 @@ gdm_slave_finalize (GObject *object) g_return_if_fail (slave->priv != NULL); - g_free (slave->priv->display_id); g_free (slave->priv->display_name); g_free (slave->priv->display_hostname); g_free (slave->priv->display_seat_id); @@ -1736,13 +877,3 @@ gdm_slave_finalize (GObject *object) G_OBJECT_CLASS (gdm_slave_parent_class)->finalize (object); } - -void -gdm_slave_export_interface (GdmSlave *slave, - GDBusInterfaceSkeleton *interface) -{ - g_dbus_interface_skeleton_export (interface, - slave->priv->connection, - GDM_SLAVE_PATH, - NULL); -} diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h index 57cf2bea..0db182f0 100644 --- a/daemon/gdm-slave.h +++ b/daemon/gdm-slave.h @@ -50,22 +50,10 @@ typedef struct gboolean (*start) (GdmSlave *slave); gboolean (*stop) (GdmSlave *slave); - gboolean (*open_session) (GdmSlave *slave, - GPid pid_of_caller, - uid_t uid_of_caller, - const char **address, - GError **error); - - void (*open_reauthentication_channel) (GdmSlave *slave, - const char *username, - GPid pid_of_caller, - uid_t uid_of_caller, - GAsyncReadyCallback callback, - gpointer user_data, - GCancellable *cancellable); - char * (*open_reauthentication_channel_finish) (GdmSlave *slave, - GAsyncResult *result, - GError **error); + void (* set_up_greeter_session) (GdmSlave *slave, + char **username); + void (* start_greeter_session) (GdmSlave *slave); + void (* stop_greeter_session) (GdmSlave *slave); /* signals */ void (*stopped) (GdmSlave *slave); @@ -85,30 +73,23 @@ GQuark gdm_slave_error_quark (void); GType gdm_slave_get_type (void); gboolean gdm_slave_start (GdmSlave *slave); gboolean gdm_slave_stop (GdmSlave *slave); - -char * gdm_slave_get_primary_session_id_for_user (GdmSlave *slave, - const char *username); - gboolean gdm_slave_get_timed_login_details (GdmSlave *slave, gboolean *enabled, char **username, int *delay); - gboolean gdm_slave_add_user_authorization (GdmSlave *slave, const char *username, char **filename); -gboolean gdm_slave_switch_to_user_session (GdmSlave *slave, - const char *username, - const char *session_id, - gboolean fail_if_already_switched); - gboolean gdm_slave_connect_to_x11_display (GdmSlave *slave); void gdm_slave_set_initial_cursor_position (GdmSlave *slave); -void gdm_slave_export_interface (GdmSlave *slave, - GDBusInterfaceSkeleton *interface); +void gdm_slave_set_up_greeter_session (GdmSlave *slave, + char **username); +void gdm_slave_start_greeter_session (GdmSlave *slave); +void gdm_slave_stop_greeter_session (GdmSlave *slave); + G_END_DECLS #endif /* __GDM_SLAVE_H */ diff --git a/daemon/gdm-slave.xml b/daemon/gdm-slave.xml deleted file mode 100644 index d0552521..00000000 --- a/daemon/gdm-slave.xml +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> -<node> - <interface name="org.gnome.DisplayManager.Slave"> - <method name="OpenSession"> - <arg name="pid_of_caller" type="i" direction="in" /> - <arg name="uid_of_caller" type="i" direction="in" /> - <arg name="address" type="s" direction="out" /> - </method> - - <method name="OpenReauthenticationChannel"> - <arg name="username" type="s" direction="in" /> - <arg name="pid_of_caller" type="i" direction="in" /> - <arg name="uid_of_caller" type="i" direction="in" /> - <arg name="address" type="s" direction="out" /> - </method> - - <property name="session_id" type="s" access="read"/> - </interface> -</node> diff --git a/daemon/gdm-xdmcp-chooser-display.c b/daemon/gdm-xdmcp-chooser-display.c index 706d2e8a..72e3d07f 100644 --- a/daemon/gdm-xdmcp-chooser-display.c +++ b/daemon/gdm-xdmcp-chooser-display.c @@ -37,23 +37,11 @@ #include "gdm-display.h" #include "gdm-xdmcp-chooser-display.h" -#include "gdm-xdmcp-chooser-slave-glue.h" +#include "gdm-xdmcp-chooser-slave.h" #include "gdm-common.h" #include "gdm-address.h" -#define DEFAULT_SLAVE_COMMAND LIBEXECDIR"/gdm-xdmcp-chooser-slave" - - -#define GDM_SLAVE_PATH "/org/gnome/DisplayManager/Slave" - -#define GDM_XDMCP_CHOOSER_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_XDMCP_CHOOSER_DISPLAY, GdmXdmcpChooserDisplayPrivate)) - -struct GdmXdmcpChooserDisplayPrivate -{ - GdmDBusXdmcpChooserSlave *slave_proxy; -}; - enum { HOSTNAME_SELECTED, LAST_SIGNAL @@ -63,13 +51,13 @@ static guint signals [LAST_SIGNAL] = { 0, }; static void gdm_xdmcp_chooser_display_class_init (GdmXdmcpChooserDisplayClass *klass); static void gdm_xdmcp_chooser_display_init (GdmXdmcpChooserDisplay *xdmcp_chooser_display); -static void gdm_xdmcp_chooser_display_finalize (GObject *object); -static gboolean gdm_xdmcp_chooser_display_finish (GdmDisplay *display); +static gboolean gdm_xdmcp_chooser_display_prepare (GdmDisplay *display); +static gboolean gdm_xdmcp_chooser_display_finish (GdmDisplay *display); G_DEFINE_TYPE (GdmXdmcpChooserDisplay, gdm_xdmcp_chooser_display, GDM_TYPE_XDMCP_DISPLAY) static void -on_hostname_selected (GdmDBusXdmcpChooserSlave *proxy, +on_hostname_selected (GdmXdmcpChooserSlave *slave, const char *hostname, GdmXdmcpChooserDisplay *display) { @@ -77,57 +65,13 @@ on_hostname_selected (GdmDBusXdmcpChooserSlave *proxy, g_signal_emit (display, signals [HOSTNAME_SELECTED], 0, hostname); } -static gboolean -gdm_xdmcp_chooser_display_set_slave_bus_name (GdmDisplay *display, - const char *name, - GError **error) -{ - GDBusConnection *connection; - GError *local_error; - GdmXdmcpChooserDisplay *chooser_display; - - chooser_display = GDM_XDMCP_CHOOSER_DISPLAY (display); - g_clear_object (&chooser_display->priv->slave_proxy); - - local_error = NULL; - connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error); - if (connection == NULL) { - g_critical ("error getting system bus: %s", local_error->message); - g_error_free (local_error); - } - - g_debug ("GdmXdmcpChooserDisplay: creating proxy for slave on %s" , name); - - chooser_display->priv->slave_proxy = GDM_DBUS_XDMCP_CHOOSER_SLAVE ( - gdm_dbus_xdmcp_chooser_slave_proxy_new_sync (connection, - G_DBUS_PROXY_FLAGS_NONE, - name, - GDM_SLAVE_PATH, - NULL, - &local_error)); - if (chooser_display->priv->slave_proxy == NULL) { - g_warning ("Failed to connect to the slave object: %s", local_error->message); - g_error_free (local_error); - goto out; - } - - g_signal_connect (chooser_display->priv->slave_proxy, - "hostname-selected", - G_CALLBACK (on_hostname_selected), - display); - out: - return GDM_DISPLAY_CLASS (gdm_xdmcp_chooser_display_parent_class)->set_slave_bus_name (display, name, error); -} - static void gdm_xdmcp_chooser_display_class_init (GdmXdmcpChooserDisplayClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass); - object_class->finalize = gdm_xdmcp_chooser_display_finalize; - - display_class->set_slave_bus_name = gdm_xdmcp_chooser_display_set_slave_bus_name; + display_class->prepare = gdm_xdmcp_chooser_display_prepare; display_class->finish = gdm_xdmcp_chooser_display_finish; signals [HOSTNAME_SELECTED] = @@ -141,32 +85,27 @@ gdm_xdmcp_chooser_display_class_init (GdmXdmcpChooserDisplayClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); - - g_type_class_add_private (klass, sizeof (GdmXdmcpChooserDisplayPrivate)); } static void gdm_xdmcp_chooser_display_init (GdmXdmcpChooserDisplay *xdmcp_chooser_display) { - - xdmcp_chooser_display->priv = GDM_XDMCP_CHOOSER_DISPLAY_GET_PRIVATE (xdmcp_chooser_display); } -static void -gdm_xdmcp_chooser_display_finalize (GObject *object) +static gboolean +gdm_xdmcp_chooser_display_prepare (GdmDisplay *display) { - GdmXdmcpChooserDisplay *chooser_display; + GdmXdmcpChooserSlave *slave; - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_XDMCP_CHOOSER_DISPLAY (object)); + if (!GDM_DISPLAY_CLASS (gdm_xdmcp_chooser_display_parent_class)->prepare (display)) + return FALSE; - chooser_display = GDM_XDMCP_CHOOSER_DISPLAY (object); + slave = GDM_XDMCP_CHOOSER_SLAVE (gdm_display_get_slave (display)); - g_return_if_fail (chooser_display->priv != NULL); + g_signal_connect (slave, "hostname-selected", + G_CALLBACK (on_hostname_selected), display); - g_clear_object (&chooser_display->priv->slave_proxy); - - G_OBJECT_CLASS (gdm_xdmcp_chooser_display_parent_class)->finalize (object); + return TRUE; } static gboolean @@ -192,7 +131,7 @@ gdm_xdmcp_chooser_display_new (const char *hostname, x11_display = g_strdup_printf ("%s:%d", hostname, number); object = g_object_new (GDM_TYPE_XDMCP_CHOOSER_DISPLAY, - "slave-command", DEFAULT_SLAVE_COMMAND, + "slave-type", GDM_TYPE_XDMCP_CHOOSER_SLAVE, "remote-hostname", hostname, "x11-display-number", number, "x11-display-name", x11_display, diff --git a/daemon/gdm-xdmcp-chooser-display.h b/daemon/gdm-xdmcp-chooser-display.h index 86cef656..7890afa5 100644 --- a/daemon/gdm-xdmcp-chooser-display.h +++ b/daemon/gdm-xdmcp-chooser-display.h @@ -43,7 +43,6 @@ typedef struct GdmXdmcpChooserDisplayPrivate GdmXdmcpChooserDisplayPrivate; typedef struct { GdmXdmcpDisplay parent; - GdmXdmcpChooserDisplayPrivate *priv; } GdmXdmcpChooserDisplay; typedef struct diff --git a/daemon/gdm-xdmcp-chooser-slave.c b/daemon/gdm-xdmcp-chooser-slave.c index 666f2a83..da26a952 100644 --- a/daemon/gdm-xdmcp-chooser-slave.c +++ b/daemon/gdm-xdmcp-chooser-slave.c @@ -39,7 +39,6 @@ #include "gdm-common.h" #include "gdm-xdmcp-chooser-slave.h" -#include "gdm-xdmcp-chooser-slave-glue.h" #include "gdm-server.h" #include "gdm-launch-environment.h" @@ -65,17 +64,21 @@ struct GdmXdmcpChooserSlavePrivate guint connection_attempts; GdmLaunchEnvironment *chooser_environment; +}; - GdmDBusXdmcpChooserSlave *skeleton; +enum { + HOSTNAME_SELECTED, + LAST_SIGNAL }; +static guint signals [LAST_SIGNAL] = { 0, }; + static void gdm_xdmcp_chooser_slave_class_init (GdmXdmcpChooserSlaveClass *klass); static void gdm_xdmcp_chooser_slave_init (GdmXdmcpChooserSlave *xdmcp_chooser_slave); static void gdm_xdmcp_chooser_slave_finalize (GObject *object); G_DEFINE_TYPE (GdmXdmcpChooserSlave, gdm_xdmcp_chooser_slave, GDM_TYPE_SLAVE) - static void on_chooser_session_opened (GdmLaunchEnvironment *chooser, GdmXdmcpChooserSlave *slave) @@ -137,8 +140,7 @@ on_chooser_hostname_selected (GdmSession *session, GdmXdmcpChooserSlave *slave) { g_debug ("GdmXdmcpChooserSlave: connecting to host %s", name); - gdm_dbus_xdmcp_chooser_slave_emit_hostname_selected (slave->priv->skeleton, - name); + g_signal_emit (slave, signals [HOSTNAME_SELECTED], 0, name); } static void @@ -348,63 +350,29 @@ gdm_xdmcp_chooser_slave_stop (GdmSlave *slave) return TRUE; } -static gboolean -gdm_xdmcp_chooser_slave_open_session (GdmSlave *slave, - GPid pid_of_caller, - uid_t uid_of_caller, - const char **address, - GError **error) -{ - GdmXdmcpChooserSlave *self = GDM_XDMCP_CHOOSER_SLAVE (slave); - GdmSession *session; - - session = gdm_launch_environment_get_session (GDM_LAUNCH_ENVIRONMENT (self->priv->chooser_environment)); - - if (gdm_session_client_is_connected (session)) { - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Currently, only one client can be connected at once")); - - return FALSE; - } - - *address = gdm_session_get_server_address (session); - return TRUE; -} - -static GObject * -gdm_xdmcp_chooser_slave_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GdmXdmcpChooserSlave *slave; - - slave = GDM_XDMCP_CHOOSER_SLAVE (G_OBJECT_CLASS (gdm_xdmcp_chooser_slave_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - slave->priv->skeleton = GDM_DBUS_XDMCP_CHOOSER_SLAVE (gdm_dbus_xdmcp_chooser_slave_skeleton_new ()); - gdm_slave_export_interface (GDM_SLAVE (slave), - G_DBUS_INTERFACE_SKELETON (slave->priv->skeleton)); - - return G_OBJECT (slave); -} - static void gdm_xdmcp_chooser_slave_class_init (GdmXdmcpChooserSlaveClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass); - object_class->constructor = gdm_xdmcp_chooser_slave_constructor; object_class->finalize = gdm_xdmcp_chooser_slave_finalize; slave_class->start = gdm_xdmcp_chooser_slave_start; slave_class->stop = gdm_xdmcp_chooser_slave_stop; - slave_class->open_session = gdm_xdmcp_chooser_slave_open_session; g_type_class_add_private (klass, sizeof (GdmXdmcpChooserSlavePrivate)); + + signals [HOSTNAME_SELECTED] = + g_signal_new ("hostname-selected", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, G_TYPE_STRING); } static void @@ -423,23 +391,7 @@ gdm_xdmcp_chooser_slave_finalize (GObject *object) xdmcp_chooser_slave = GDM_XDMCP_CHOOSER_SLAVE (object); - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (xdmcp_chooser_slave->priv->skeleton)); - - g_clear_object (&xdmcp_chooser_slave->priv->skeleton); - g_return_if_fail (xdmcp_chooser_slave->priv != NULL); G_OBJECT_CLASS (gdm_xdmcp_chooser_slave_parent_class)->finalize (object); } - -GdmSlave * -gdm_xdmcp_chooser_slave_new (const char *id) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_XDMCP_CHOOSER_SLAVE, - "display-id", id, - NULL); - - return GDM_SLAVE (object); -} diff --git a/daemon/gdm-xdmcp-chooser-slave.h b/daemon/gdm-xdmcp-chooser-slave.h index e5b5e479..b948ef8d 100644 --- a/daemon/gdm-xdmcp-chooser-slave.h +++ b/daemon/gdm-xdmcp-chooser-slave.h @@ -49,7 +49,6 @@ typedef struct } GdmXdmcpChooserSlaveClass; GType gdm_xdmcp_chooser_slave_get_type (void); -GdmSlave * gdm_xdmcp_chooser_slave_new (const char *id); G_END_DECLS diff --git a/daemon/gdm-xdmcp-chooser-slave.xml b/daemon/gdm-xdmcp-chooser-slave.xml deleted file mode 100644 index 06170e2a..00000000 --- a/daemon/gdm-xdmcp-chooser-slave.xml +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> -<node> - <interface name="org.gnome.DisplayManager.XdmcpChooserSlave"> - <signal name="HostnameSelected"> - <arg name="hostname" type="s"/> - </signal> - </interface> -</node> diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c index 28b03007..7fb26d6a 100644 --- a/daemon/gdm-xdmcp-display-factory.c +++ b/daemon/gdm-xdmcp-display-factory.c @@ -2363,11 +2363,13 @@ gdm_xdmcp_handle_request (GdmXdmcpDisplayFactory *factory, ARRAY8 authorization_name; ARRAY8 authorization_data; gint32 session_number; - GArray *cookie; + const char *x11_cookie; + gsize x11_cookie_size; char *name; - cookie = NULL; - gdm_display_get_x11_cookie (display, &cookie, NULL); + x11_cookie = NULL; + x11_cookie_size = 0; + gdm_display_get_x11_cookie (display, &x11_cookie, &x11_cookie_size, NULL); name = NULL; gdm_display_get_x11_display_name (display, &name, NULL); @@ -2375,12 +2377,12 @@ gdm_xdmcp_handle_request (GdmXdmcpDisplayFactory *factory, g_debug ("GdmXdmcpDisplayFactory: Sending authorization key for display %s", name ? name : "(null)"); g_free (name); - g_debug ("GdmXdmcpDisplayFactory: cookie len %d", (int) cookie->len); + g_debug ("GdmXdmcpDisplayFactory: cookie len %d", (int) x11_cookie_size); session_number = gdm_xdmcp_display_get_session_number (GDM_XDMCP_DISPLAY (display)); /* the send accept will fail if cookie is null */ - g_assert (cookie != NULL); + g_assert (x11_cookie != NULL); authentication_name.data = NULL; authentication_name.length = 0; @@ -2390,8 +2392,8 @@ gdm_xdmcp_handle_request (GdmXdmcpDisplayFactory *factory, authorization_name.data = (CARD8 *) "MIT-MAGIC-COOKIE-1"; authorization_name.length = strlen ((char *) authorization_name.data); - authorization_data.data = (CARD8 *) cookie->data; - authorization_data.length = cookie->len; + authorization_data.data = (CARD8 *) x11_cookie; + authorization_data.length = x11_cookie_size; /* the addrs are NOT copied */ gdm_xdmcp_send_accept (factory, @@ -2401,8 +2403,6 @@ gdm_xdmcp_handle_request (GdmXdmcpDisplayFactory *factory, &authentication_data, &authorization_name, &authorization_data); - - g_array_free (cookie, TRUE); } } } else { diff --git a/daemon/simple-slave-main.c b/daemon/simple-slave-main.c deleted file mode 100644 index a94a5ad0..00000000 --- a/daemon/simple-slave-main.c +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <locale.h> - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gio/gio.h> - -#include "gdm-xerrors.h" -#include "gdm-log.h" -#include "gdm-common.h" -#include "gdm-simple-slave.h" -#include "gdm-settings.h" -#include "gdm-settings-direct.h" -#include "gdm-settings-keys.h" - -static GdmSettings *settings = NULL; -static int gdm_return_code = 0; - -static GDBusConnection * -get_system_bus (void) -{ - GError *error; - GDBusConnection *bus; - - error = NULL; - bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (bus == NULL) { - g_warning ("Couldn't connect to system bus: %s", - error->message); - g_error_free (error); - goto out; - } - - g_dbus_connection_set_exit_on_close (bus, FALSE); - - out: - return bus; -} - -static gboolean -on_shutdown_signal_cb (gpointer user_data) -{ - GMainLoop *mainloop = user_data; - - g_main_loop_quit (mainloop); - - return FALSE; -} - -static gboolean -on_sigusr2_cb (gpointer user_data) -{ - g_debug ("Got USR2 signal"); - - gdm_log_toggle_debug (); - - return TRUE; -} - -static void -on_slave_stopped (GdmSlave *slave, - GMainLoop *main_loop) -{ - g_debug ("slave finished"); - gdm_return_code = 0; - g_main_loop_quit (main_loop); -} - -static gboolean -is_debug_set (void) -{ - gboolean debug; - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - return debug; -} - -int -main (int argc, - char **argv) -{ - GMainLoop *main_loop; - GOptionContext *context; - GDBusConnection *connection; - GdmSlave *slave; - static char *display_id = NULL; - static GOptionEntry entries [] = { - { "display-id", 0, 0, G_OPTION_ARG_STRING, &display_id, N_("Display ID"), N_("ID") }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - context = g_option_context_new (_("GNOME Display Manager Slave")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - /* For debugging */ - /*sleep (10);*/ - - connection = get_system_bus (); - if (connection == NULL) { - goto out; - } - - gdm_xerrors_init (); - gdm_log_init (); - - settings = gdm_settings_new (); - if (settings == NULL) { - g_warning ("Unable to initialize settings"); - goto out; - } - - if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) { - g_warning ("Unable to initialize settings"); - goto out; - } - - gdm_log_set_debug (is_debug_set ()); - - if (display_id == NULL) { - g_critical ("No display ID set"); - exit (1); - } - - main_loop = g_main_loop_new (NULL, FALSE); - - g_unix_signal_add (SIGTERM, on_shutdown_signal_cb, main_loop); - g_unix_signal_add (SIGINT, on_shutdown_signal_cb, main_loop); - g_unix_signal_add (SIGUSR2, on_sigusr2_cb, NULL); - - slave = gdm_simple_slave_new (display_id); - if (slave == NULL) { - goto out; - } - g_signal_connect (slave, - "stopped", - G_CALLBACK (on_slave_stopped), - main_loop); - gdm_slave_start (slave); - - g_main_loop_run (main_loop); - - if (slave != NULL) { - g_object_unref (slave); - } - - g_main_loop_unref (main_loop); - - out: - g_debug ("Slave finished"); - - g_object_unref (connection); - - return gdm_return_code; -} diff --git a/daemon/xdmcp-chooser-slave-main.c b/daemon/xdmcp-chooser-slave-main.c deleted file mode 100644 index 302466b0..00000000 --- a/daemon/xdmcp-chooser-slave-main.c +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> -#include <locale.h> - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> -#include <gio/gio.h> - -#include "gdm-xerrors.h" -#include "gdm-log.h" -#include "gdm-common.h" -#include "gdm-xdmcp-chooser-slave.h" - -#include "gdm-settings.h" -#include "gdm-settings-direct.h" -#include "gdm-settings-keys.h" - -static GdmSettings *settings = NULL; -static int gdm_return_code = 0; - -static GDBusConnection * -get_system_bus (void) -{ - GError *error; - GDBusConnection *bus; - - error = NULL; - bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (bus == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - goto out; - } - - g_dbus_connection_set_exit_on_close (bus, FALSE); - - out: - return bus; -} - -static void -on_slave_stopped (GdmSlave *slave, - GMainLoop *main_loop) -{ - g_debug ("slave finished"); - gdm_return_code = 0; - g_main_loop_quit (main_loop); -} - -static gboolean -on_shutdown_signal_cb (gpointer user_data) -{ - GMainLoop *mainloop = user_data; - - g_main_loop_quit (mainloop); - - return FALSE; -} - -static gboolean -on_sigusr2_cb (gpointer user_data) -{ - g_debug ("Got USR2 signal"); - - gdm_log_toggle_debug (); - - return TRUE; -} - -static gboolean -is_debug_set (void) -{ - gboolean debug; - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - return debug; -} - -int -main (int argc, - char **argv) -{ - GMainLoop *main_loop; - GOptionContext *context; - GDBusConnection *connection; - GdmSlave *slave; - static char *display_id = NULL; - static GOptionEntry entries [] = { - { "display-id", 0, 0, G_OPTION_ARG_STRING, &display_id, N_("Display ID"), N_("ID") }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - context = g_option_context_new (_("GNOME Display Manager Slave")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - connection = get_system_bus (); - if (connection == NULL) { - goto out; - } - - gdm_xerrors_init (); - gdm_log_init (); - - settings = gdm_settings_new (); - if (settings == NULL) { - g_warning ("Unable to initialize settings"); - goto out; - } - - if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) { - g_warning ("Unable to initialize settings"); - goto out; - } - - gdm_log_set_debug (is_debug_set ()); - - if (display_id == NULL) { - g_critical ("No display ID set"); - exit (1); - } - - main_loop = g_main_loop_new (NULL, FALSE); - - g_unix_signal_add (SIGTERM, on_shutdown_signal_cb, main_loop); - g_unix_signal_add (SIGINT, on_shutdown_signal_cb, main_loop); - g_unix_signal_add (SIGUSR2, on_sigusr2_cb, NULL); - - slave = gdm_xdmcp_chooser_slave_new (display_id); - if (slave == NULL) { - goto out; - } - g_signal_connect (slave, - "stopped", - G_CALLBACK (on_slave_stopped), - main_loop); - gdm_slave_start (slave); - - g_main_loop_run (main_loop); - - if (slave != NULL) { - g_object_unref (slave); - } - - g_main_loop_unref (main_loop); - - out: - g_debug ("Slave finished"); - - g_object_unref (connection); - - return gdm_return_code; -} |