2 * Copyright (C) 2010-2011 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
15 #include <gio/gdesktopappinfo.h>
18 #include "configuration.h"
20 #include "pam-session.h"
22 #include "ldm-marshal.h"
24 #include "xserver-local.h" // FIXME: Shouldn't know if it's an xserver
37 static guint signals[LAST_SIGNAL] = { 0 };
42 SESSION_GREETER_PRE_CONNECT,
44 SESSION_GREETER_AUTHENTICATED,
51 DisplayServer *display_server;
53 /* User to run greeter as */
57 gchar *greeter_session;
59 /* TRUE if the user list should be shown */
60 gboolean greeter_hide_users;
62 /* Session requested to log into */
65 /* Directory to load X sessions from */
68 /* Directory to load X greeters from */
71 /* Program to run sessions through */
72 gchar *session_wrapper;
74 /* PAM service to authenticate against */
77 /* PAM service to authenticate against for automatic logins */
78 gchar *pam_autologin_service;
80 /* TRUE if in a user session */
81 gboolean in_user_session;
83 /* TRUE if have emitted ready signal */
84 gboolean indicated_ready;
89 /* Communication link to greeter */
92 /* Current PAM session */
93 PAMSession *pam_session;
95 /* User that should be automatically logged in */
96 gchar *autologin_user;
97 gboolean autologin_guest;
98 gint autologin_timeout;
100 /* TRUE if start greeter if fail to login */
101 gboolean start_greeter_if_fail;
103 /* Hint to select user in greeter */
104 gchar *select_user_hint;
105 gboolean select_guest_hint;
107 /* TRUE if allowed to log into guest account */
108 gboolean allow_guest;
110 /* TRUE if stopping the display (waiting for dispaly server, greeter and session to stop) */
114 G_DEFINE_TYPE (Display, display, G_TYPE_OBJECT);
116 static gboolean start_greeter_session (Display *display);
117 static gboolean start_user_session (Display *display);
119 // FIXME: Should be a construct property
120 // FIXME: Move into seat.c
122 display_load_config (Display *display, const gchar *config_section)
124 g_return_if_fail (display != NULL);
126 display->priv->greeter_user = config_get_string (config_get_instance (), "LightDM", "greeter-user");
129 display->priv->greeter_session = config_get_string (config_get_instance (), config_section, "greeter-session");
130 if (!display->priv->greeter_session)
131 display->priv->greeter_session = config_get_string (config_get_instance (), "SeatDefaults", "greeter-session");
132 if (config_section && config_has_key (config_get_instance (), config_section, "greeter-hide-users"))
133 display->priv->greeter_hide_users = config_get_boolean (config_get_instance (), config_section, "greeter-hide-users");
134 else if (config_has_key (config_get_instance (), "SeatDefaults", "greeter-hide-users"))
135 display->priv->greeter_hide_users = config_get_boolean (config_get_instance (), "SeatDefaults", "greeter-hide-users");
137 display->priv->user_session = config_get_string (config_get_instance (), config_section, "user-session");
138 if (!display->priv->user_session)
139 display->priv->user_session = config_get_string (config_get_instance (), "SeatDefaults", "user-session");
141 display->priv->xsessions_dir = config_get_string (config_get_instance (), config_section, "xsessions-directory");
142 if (!display->priv->xsessions_dir)
143 display->priv->xsessions_dir = config_get_string (config_get_instance (), "SeatDefaults", "xsessions-directory");
145 display->priv->xgreeters_dir = config_get_string (config_get_instance (), config_section, "xgreeters-directory");
146 if (!display->priv->xgreeters_dir)
147 display->priv->xgreeters_dir = config_get_string (config_get_instance (), "SeatDefaults", "xgreeters-directory");
149 display->priv->session_wrapper = config_get_string (config_get_instance (), config_section, "session-wrapper");
150 if (!display->priv->session_wrapper)
151 display->priv->session_wrapper = config_get_string (config_get_instance (), "SeatDefaults", "session-wrapper");
154 // FIXME: Should be a construct property
156 display_set_display_server (Display *display, DisplayServer *display_server)
158 g_return_if_fail (display != NULL);
159 g_return_if_fail (display->priv->display_server == NULL);
160 display->priv->display_server = g_object_ref (display_server);
164 display_get_display_server (Display *display)
166 g_return_val_if_fail (display != NULL, NULL);
167 return display->priv->display_server;
171 display_get_username (Display *display)
173 g_return_val_if_fail (display != NULL, NULL);
175 if (display->priv->pam_session && display->priv->in_user_session)
176 return pam_session_get_username (display->priv->pam_session);
182 display_get_session (Display *display)
184 g_return_val_if_fail (display != NULL, NULL);
185 return display->priv->session;
189 display_set_allow_guest (Display *display, gboolean allow_guest)
191 g_return_if_fail (display != NULL);
192 display->priv->allow_guest = allow_guest;
196 display_set_autologin_user (Display *display, const gchar *username, gboolean is_guest, gint timeout)
198 g_return_if_fail (display != NULL);
199 g_free (display->priv->autologin_user);
200 display->priv->autologin_user = g_strdup (username);
201 display->priv->autologin_guest = is_guest;
202 display->priv->autologin_timeout = timeout;
206 display_set_select_user_hint (Display *display, const gchar *username, gboolean is_guest)
208 g_return_if_fail (display != NULL);
209 g_free (display->priv->select_user_hint);
210 display->priv->select_user_hint = g_strdup (username);
211 display->priv->select_guest_hint = is_guest;
215 display_set_user_session (Display *display, const gchar *session_name)
217 g_return_if_fail (display != NULL);
220 g_free (display->priv->user_session);
221 display->priv->user_session = g_strdup (session_name);
226 switch_to_user (Display *display, const gchar *username)
229 g_signal_emit (display, signals[SWITCH_TO_USER], 0, username, &result);
234 switch_to_guest (Display *display)
237 g_signal_emit (display, signals[SWITCH_TO_GUEST], 0, &result);
242 get_guest_username (Display *display)
245 g_signal_emit (display, signals[GET_GUEST_USERNAME], 0, &username);
250 start_ck_session (Display *display, const gchar *session_type, User *user)
253 const gchar *hostname = "";
254 GVariantBuilder arg_builder;
256 gchar *cookie = NULL;
257 GError *error = NULL;
259 /* Only start ConsoleKit sessions when running as root */
263 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
264 G_DBUS_PROXY_FLAGS_NONE,
266 "org.freedesktop.ConsoleKit",
267 "/org/freedesktop/ConsoleKit/Manager",
268 "org.freedesktop.ConsoleKit.Manager",
271 g_warning ("Unable to get connection to ConsoleKit: %s", error->message);
272 g_clear_error (&error);
276 g_variant_builder_init (&arg_builder, G_VARIANT_TYPE ("(a(sv))"));
277 g_variant_builder_open (&arg_builder, G_VARIANT_TYPE ("a(sv)"));
278 g_variant_builder_add (&arg_builder, "(sv)", "unix-user", g_variant_new_int32 (user_get_uid (user)));
279 g_variant_builder_add (&arg_builder, "(sv)", "session-type", g_variant_new_string (session_type));
280 if (IS_XSERVER (display->priv->display_server))
282 g_variant_builder_add (&arg_builder, "(sv)", "x11-display",
283 g_variant_new_string (xserver_get_address (XSERVER (display->priv->display_server))));
285 if (IS_XSERVER_LOCAL (display->priv->display_server) && xserver_local_get_vt (XSERVER_LOCAL (display->priv->display_server)) >= 0)
287 gchar *display_device;
288 display_device = g_strdup_printf ("/dev/tty%d", xserver_local_get_vt (XSERVER_LOCAL (display->priv->display_server)));
289 g_variant_builder_add (&arg_builder, "(sv)", "x11-display-device", g_variant_new_string (display_device));
290 g_free (display_device);
294 g_variant_builder_add (&arg_builder, "(sv)", "remote-host-name", g_variant_new_string (hostname));
295 g_variant_builder_add (&arg_builder, "(sv)", "is-local", g_variant_new_boolean (TRUE));
296 g_variant_builder_close (&arg_builder);
298 result = g_dbus_proxy_call_sync (proxy,
299 "OpenSessionWithParameters",
300 g_variant_builder_end (&arg_builder),
301 G_DBUS_CALL_FLAGS_NONE,
305 g_object_unref (proxy);
308 g_warning ("Failed to open CK session: %s", error->message);
309 g_clear_error (&error);
313 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
314 g_variant_get (result, "(s)", &cookie);
316 g_warning ("Unexpected response from OpenSessionWithParameters: %s", g_variant_get_type_string (result));
317 g_variant_unref (result);
320 g_debug ("Opened ConsoleKit session %s", cookie);
326 end_ck_session (const gchar *cookie)
330 GError *error = NULL;
335 g_debug ("Ending ConsoleKit session %s", cookie);
337 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
338 G_DBUS_PROXY_FLAGS_NONE,
340 "org.freedesktop.ConsoleKit",
341 "/org/freedesktop/ConsoleKit/Manager",
342 "org.freedesktop.ConsoleKit.Manager",
344 result = g_dbus_proxy_call_sync (proxy,
346 g_variant_new ("(s)", cookie),
347 G_DBUS_CALL_FLAGS_NONE,
351 g_object_unref (proxy);
354 g_warning ("Error ending ConsoleKit session: %s", error->message);
355 g_clear_error (&error);
359 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
362 g_variant_get (result, "(b)", &is_closed);
364 g_warning ("ConsoleKit.Manager.CloseSession() returned false");
367 g_warning ("Unexpected response from CloseSession: %s", g_variant_get_type_string (result));
369 g_variant_unref (result);
373 set_env_from_pam_session (Session *session, PAMSession *pam_session)
377 pam_env = pam_session_get_envlist (pam_session);
383 env_string = g_strjoinv (" ", pam_env);
384 g_debug ("PAM returns environment '%s'", env_string);
387 for (i = 0; pam_env[i]; i++)
389 gchar **pam_env_vars = g_strsplit (pam_env[i], "=", 2);
390 if (pam_env_vars && pam_env_vars[0] && pam_env_vars[1])
391 process_set_env (PROCESS (session), pam_env_vars[0], pam_env_vars[1]);
393 g_warning ("Can't parse PAM environment variable %s", pam_env[i]);
394 g_strfreev (pam_env_vars);
396 g_strfreev (pam_env);
401 session_exited_cb (Session *session, gint status, Display *display)
404 g_debug ("Session exited with value %d", status);
408 session_terminated_cb (Session *session, gint signum, Display *display)
410 g_debug ("Session terminated with signal %d", signum);
414 check_stopped (Display *display)
416 if (display->priv->stopping &&
417 display->priv->display_server == NULL &&
418 display->priv->session == NULL)
420 g_debug ("Display stopped");
421 g_signal_emit (display, signals[STOPPED], 0);
426 autologin_pam_message_cb (PAMSession *session, int num_msg, const struct pam_message **msg, Display *display)
428 g_debug ("Aborting automatic login as PAM requests input");
429 pam_session_cancel (session);
433 autologin_authentication_result_cb (PAMSession *session, int result, Display *display)
435 g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
436 if (display->priv->stopping)
439 gboolean started_session = FALSE;
441 if (result == PAM_SUCCESS)
443 g_debug ("User %s authorized", pam_session_get_username (display->priv->pam_session));
444 pam_session_open (display->priv->pam_session);
445 started_session = start_user_session (display);
446 if (!started_session)
447 g_debug ("Failed to start autologin session");
450 g_debug ("Autologin failed authentication");
452 if (!started_session && display->priv->start_greeter_if_fail)
454 display_set_autologin_user (display, NULL, FALSE, 0);
455 if (display->priv->autologin_user)
456 display_set_select_user_hint (display, display->priv->autologin_user, FALSE);
457 started_session = start_greeter_session (display);
460 if (!started_session)
461 display_stop (display);
465 autologin (Display *display, const gchar *username, gboolean start_greeter_if_fail)
468 GError *error = NULL;
470 display->priv->start_greeter_if_fail = start_greeter_if_fail;
472 display->priv->in_user_session = TRUE;
473 display->priv->pam_session = pam_session_new (display->priv->pam_autologin_service, username);
474 g_signal_connect (display->priv->pam_session, "got-messages", G_CALLBACK (autologin_pam_message_cb), display);
475 g_signal_connect (display->priv->pam_session, "authentication-result", G_CALLBACK (autologin_authentication_result_cb), display);
477 result = pam_session_authenticate (display->priv->pam_session, &error);
480 g_debug ("Failed to start autologin session for %s: %s", username, error->message);
481 g_signal_handlers_disconnect_matched (display->priv->pam_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
482 g_object_unref (display->priv->pam_session);
483 display->priv->pam_session = NULL;
485 g_clear_error (&error);
491 autologin_guest (Display *display, gboolean start_greeter_if_fail)
496 username = get_guest_username (display);
499 result = autologin (display, username, start_greeter_if_fail);
506 cleanup_after_session (Display *display)
508 /* Close ConsoleKit session */
510 end_ck_session (session_get_cookie (display->priv->session));
512 /* Close PAM session */
513 g_signal_handlers_disconnect_matched (display->priv->pam_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
514 pam_session_close (display->priv->pam_session);
515 g_object_unref (display->priv->pam_session);
516 display->priv->pam_session = NULL;
518 g_signal_handlers_disconnect_matched (display->priv->session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
519 g_object_unref (display->priv->session);
520 display->priv->session = NULL;
522 if (display->priv->stopping)
524 check_stopped (display);
532 greeter_session_stopped_cb (Session *session, Display *display)
534 gboolean started_session = FALSE;
536 g_debug ("Greeter quit");
538 if (cleanup_after_session (display))
541 if (!display->priv->display_server)
544 /* Start the session for the authenticated user */
545 if (greeter_get_guest_authenticated (display->priv->greeter))
547 started_session = autologin_guest (display, FALSE);
548 if (!started_session)
549 g_debug ("Failed to start guest session");
553 display->priv->in_user_session = TRUE;
554 display->priv->pam_session = g_object_ref (greeter_get_pam_session (display->priv->greeter));
555 pam_session_open (display->priv->pam_session);
556 started_session = start_user_session (display);
557 if (!started_session)
558 g_debug ("Failed to start user session");
561 g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
562 g_object_unref (display->priv->greeter);
563 display->priv->greeter = NULL;
565 if (!started_session)
566 display_stop (display);
570 user_session_stopped_cb (Session *session, Display *display)
572 g_debug ("User session quit");
574 g_signal_emit (display, signals[SESSION_STOPPED], 0);
576 if (cleanup_after_session (display))
579 /* This display has ended */
580 display_stop (display);
584 create_session (Display *display, PAMSession *pam_session, const gchar *session_name, gboolean is_greeter, const gchar *log_filename)
587 gchar *sessions_dir, *filename, *path, *orig_path, *command = NULL;
588 GKeyFile *session_desktop_file;
592 GError *error = NULL;
594 user = user_get_by_name (pam_session_get_username (pam_session));
595 g_return_val_if_fail (user != NULL, FALSE);
597 g_debug ("Starting session %s as user %s logging to %s", session_name, user_get_name (user), log_filename);
599 // FIXME: This is X specific, move into xsession.c
601 sessions_dir = display->priv->xgreeters_dir;
603 sessions_dir = display->priv->xsessions_dir;
605 filename = g_strdup_printf ("%s.desktop", session_name);
606 path = g_build_filename (sessions_dir, filename, NULL);
609 session_desktop_file = g_key_file_new ();
610 result = g_key_file_load_from_file (session_desktop_file, path, G_KEY_FILE_NONE, &error);
612 g_debug ("Failed to load session file %s: %s:", path, error->message);
613 g_clear_error (&error);
616 command = g_key_file_get_string (session_desktop_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
618 g_debug ("No command in session file %s", path);
620 g_key_file_free (session_desktop_file);
624 if (display->priv->session_wrapper && !is_greeter)
628 wrapper = g_find_program_in_path (display->priv->session_wrapper);
632 command = g_strdup_printf ("%s '%s'", wrapper, command);
638 session = DISPLAY_GET_CLASS (display)->create_session (display);
639 g_return_val_if_fail (session != NULL, NULL);
640 g_signal_connect (session, "exited", G_CALLBACK (session_exited_cb), display);
641 g_signal_connect (session, "terminated", G_CALLBACK (session_terminated_cb), display);
643 g_signal_connect (session, "stopped", G_CALLBACK (greeter_session_stopped_cb), display);
645 g_signal_connect (session, "stopped", G_CALLBACK (user_session_stopped_cb), display);
646 session_set_is_greeter (session, is_greeter);
647 session_set_user (session, user);
648 session_set_command (session, command);
650 process_set_env (PROCESS (session), "DESKTOP_SESSION", session_name); // FIXME: Apparently deprecated?
651 process_set_env (PROCESS (session), "GDMSESSION", session_name); // FIXME: Not cross-desktop
653 set_env_from_pam_session (session, pam_session);
655 /* Insert our own utility directory to PATH */
656 orig_path = process_get_env (PROCESS (session), "PATH");
657 path = g_strdup_printf ("%s:%s", PKGLIBEXEC_DIR, orig_path);
658 process_set_env (PROCESS (session), "PATH", path);
662 process_set_log_file (PROCESS (session), log_filename);
664 /* Open ConsoleKit session */
667 cookie = start_ck_session (display, is_greeter ? "LoginWindow" : "", user);
668 session_set_cookie (session, cookie);
672 session_set_cookie (session, g_getenv ("XDG_SESSION_COOKIE"));
674 /* Connect using the session bus */
677 process_set_env (PROCESS (session), "DBUS_SESSION_BUS_ADDRESS", g_getenv ("DBUS_SESSION_BUS_ADDRESS"));
678 process_set_env (PROCESS (session), "LDM_BUS", "SESSION");
679 process_set_env (PROCESS (session), "LD_LIBRARY_PATH", g_getenv ("LD_LIBRARY_PATH"));
680 process_set_env (PROCESS (session), "PATH", g_getenv ("PATH"));
683 /* Variables required for regression tests */
684 if (g_getenv ("LIGHTDM_TEST_STATUS_SOCKET"))
686 process_set_env (PROCESS (session), "LIGHTDM_TEST_STATUS_SOCKET", g_getenv ("LIGHTDM_TEST_STATUS_SOCKET"));
687 process_set_env (PROCESS (session), "LIGHTDM_TEST_CONFIG", g_getenv ("LIGHTDM_TEST_CONFIG"));
688 process_set_env (PROCESS (session), "LIGHTDM_TEST_HOME_DIR", g_getenv ("LIGHTDM_TEST_HOME_DIR"));
689 process_set_env (PROCESS (session), "LD_LIBRARY_PATH", g_getenv ("LD_LIBRARY_PATH"));
696 greeter_start_authentication_cb (Greeter *greeter, const gchar *username, Display *display)
698 return pam_session_new (display->priv->pam_service, username);
702 greeter_start_session_cb (Greeter *greeter, const gchar *session_name, Display *display)
704 /* Store the session to use, use the default if none was requested */
707 g_free (display->priv->user_session);
708 display->priv->user_session = g_strdup (session_name);
711 /* Stop this display if that session already exists and can switch to it */
712 if (greeter_get_guest_authenticated (greeter))
714 if (switch_to_guest (display))
717 /* Set to login as guest */
718 display_set_autologin_user (display, NULL, TRUE, 0);
722 if (switch_to_user (display, pam_session_get_username (greeter_get_pam_session (display->priv->greeter))))
726 /* Stop the greeter, the session will start when the greeter has quit */
727 g_debug ("Stopping greeter");
728 session_stop (display->priv->session);
734 start_greeter_session (Display *display)
737 gchar *log_dir, *filename, *log_filename;
740 g_debug ("Starting greeter session");
743 user = user_get_current ();
744 else if (display->priv->greeter_user)
746 user = user_get_by_name (display->priv->greeter_user);
749 g_debug ("Unable to start greeter, user %s does not exist", display->priv->greeter_user);
755 g_warning ("Greeter must not be run as root");
758 display->priv->in_user_session = FALSE;
759 display->priv->pam_session = pam_session_new (display->priv->pam_service, user_get_name (user));
760 pam_session_open (display->priv->pam_session);
761 g_object_unref (user);
763 log_dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
764 // FIXME: May not be an X server
765 filename = g_strdup_printf ("%s-greeter.log", xserver_get_address (XSERVER (display->priv->display_server)));
766 log_filename = g_build_filename (log_dir, filename, NULL);
770 display->priv->session = create_session (display, display->priv->pam_session, display->priv->greeter_session, TRUE, log_filename);
771 g_free (log_filename);
772 if (!display->priv->session)
775 display->priv->greeter = greeter_new (display->priv->session);
776 g_signal_connect (G_OBJECT (display->priv->greeter), "start-authentication", G_CALLBACK (greeter_start_authentication_cb), display);
777 g_signal_connect (G_OBJECT (display->priv->greeter), "start-session", G_CALLBACK (greeter_start_session_cb), display);
778 if (display->priv->autologin_timeout)
780 gchar *value = g_strdup_printf ("%d", display->priv->autologin_timeout);
781 greeter_set_hint (display->priv->greeter, "autologin-timeout", value);
783 if (display->priv->autologin_user)
784 greeter_set_hint (display->priv->greeter, "autologin-user", display->priv->autologin_user);
785 else if (display->priv->autologin_guest)
786 greeter_set_hint (display->priv->greeter, "autologin-guest", "true");
788 if (display->priv->select_user_hint)
789 greeter_set_hint (display->priv->greeter, "select-user", display->priv->select_user_hint);
790 else if (display->priv->select_guest_hint)
791 greeter_set_hint (display->priv->greeter, "select-guest", "true");
792 greeter_set_hint (display->priv->greeter, "default-session", display->priv->user_session);
793 greeter_set_allow_guest (display->priv->greeter, display->priv->allow_guest);
794 greeter_set_hint (display->priv->greeter, "has-guest-account", display->priv->allow_guest ? "true" : "false");
795 greeter_set_hint (display->priv->greeter, "hide-users", display->priv->greeter_hide_users ? "true" : "false");
797 result = greeter_start (display->priv->greeter);
800 result = session_start (SESSION (display->priv->session));
802 g_debug ("Failed to start greeter session");
806 g_debug ("Failed to start greeter protocol");
808 g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
809 g_object_unref (display->priv->greeter);
810 display->priv->greeter = NULL;
815 display->priv->indicated_ready = TRUE;
816 g_signal_emit (display, signals[READY], 0);
823 start_user_session (Display *display)
828 gboolean result = FALSE;
830 g_debug ("Starting user session");
832 user = user_get_by_name (pam_session_get_username (display->priv->pam_session));
835 g_debug ("Unable to start session, user %s does not exist", pam_session_get_username (display->priv->pam_session));
839 /* Load the users login settings (~/.dmrc) */
840 dmrc_file = dmrc_load (user_get_name (user));
842 /* Update the .dmrc with changed settings */
843 g_key_file_set_string (dmrc_file, "Desktop", "Session", display->priv->user_session);
844 dmrc_save (dmrc_file, pam_session_get_username (display->priv->pam_session));
845 g_key_file_free (dmrc_file);
847 // FIXME: Copy old error file
848 log_filename = g_build_filename (user_get_home_directory (user), ".xsession-errors", NULL);
849 g_object_unref (user);
851 display->priv->session = create_session (display, display->priv->pam_session, display->priv->user_session, FALSE, log_filename);
852 g_free (log_filename);
854 if (display->priv->session)
855 result = session_start (SESSION (display->priv->session));
859 if (!display->priv->indicated_ready)
860 g_signal_emit (display, signals[READY], 0);
861 g_signal_emit (display, signals[SESSION_STARTED], 0);
868 display_server_stopped_cb (DisplayServer *server, Display *display)
870 g_debug ("Display server stopped");
872 g_signal_handlers_disconnect_matched (display->priv->display_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
873 g_object_unref (display->priv->display_server);
874 display->priv->display_server = NULL;
876 /* Stop this display, it will be restarted by the seat if necessary */
877 display_stop (display);
881 display_server_ready_cb (DisplayServer *display_server, Display *display)
883 gboolean started_session = FALSE;
885 /* Don't run any sessions on local terminals */
886 // FIXME: Make display_server_get_has_local_session
887 if (IS_XSERVER_LOCAL (display_server) && xserver_local_get_xdmcp_server (XSERVER_LOCAL (display_server)))
890 /* Automatically log in */
891 if (display->priv->autologin_guest)
893 g_debug ("Automatically logging in as guest");
894 started_session = autologin_guest (display, TRUE);
895 if (!started_session)
896 g_debug ("Failed to autologin as guest");
898 else if (display->priv->autologin_user)
900 g_debug ("Automatically logging in user %s", display->priv->autologin_user);
901 started_session = autologin (display, display->priv->autologin_user, TRUE);
902 if (!started_session)
903 g_debug ("Failed to autologin user %s", display->priv->autologin_user);
906 /* Finally start a greeter */
907 if (!started_session)
909 started_session = start_greeter_session (display);
910 if (!started_session)
911 g_debug ("Failed to start greeter");
914 if (!started_session)
915 display_stop (display);
919 display_start (Display *display)
923 g_return_val_if_fail (display != NULL, FALSE);
925 g_signal_connect (G_OBJECT (display->priv->display_server), "ready", G_CALLBACK (display_server_ready_cb), display);
926 g_signal_connect (G_OBJECT (display->priv->display_server), "stopped", G_CALLBACK (display_server_stopped_cb), display);
927 result = display_server_start (display->priv->display_server);
929 g_signal_emit (display, signals[STARTED], 0);
935 display_stop (Display *display)
937 g_return_if_fail (display != NULL);
939 if (!display->priv->stopping)
941 g_debug ("Stopping display");
943 display->priv->stopping = TRUE;
945 if (display->priv->display_server)
946 display_server_stop (display->priv->display_server);
947 if (display->priv->session)
948 session_stop (display->priv->session);
951 check_stopped (display);
955 display_real_switch_to_user (Display *display, const gchar *username)
961 display_real_switch_to_guest (Display *display)
967 display_real_get_guest_username (Display *display)
973 display_init (Display *display)
975 display->priv = G_TYPE_INSTANCE_GET_PRIVATE (display, DISPLAY_TYPE, DisplayPrivate);
976 display->priv->pam_service = g_strdup ("lightdm");
977 display->priv->pam_autologin_service = g_strdup ("lightdm-autologin");
981 display_create_session (Display *display)
987 display_finalize (GObject *object)
991 self = DISPLAY (object);
993 if (self->priv->display_server)
994 g_object_unref (self->priv->display_server);
995 g_free (self->priv->greeter_user);
996 g_free (self->priv->greeter_session);
997 if (self->priv->greeter)
998 g_object_unref (self->priv->greeter);
999 g_free (self->priv->xsessions_dir);
1000 g_free (self->priv->xgreeters_dir);
1001 g_free (self->priv->session_wrapper);
1002 g_free (self->priv->pam_service);
1003 g_free (self->priv->pam_autologin_service);
1004 if (self->priv->session)
1006 if (session_get_cookie (self->priv->session))
1007 end_ck_session (session_get_cookie (self->priv->session));
1008 g_object_unref (self->priv->session);
1010 if (self->priv->pam_session)
1011 g_object_unref (self->priv->pam_session);
1012 g_free (self->priv->autologin_user);
1013 g_free (self->priv->select_user_hint);
1014 g_free (self->priv->user_session);
1016 G_OBJECT_CLASS (display_parent_class)->finalize (object);
1020 display_class_init (DisplayClass *klass)
1022 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1024 klass->switch_to_user = display_real_switch_to_user;
1025 klass->switch_to_guest = display_real_switch_to_guest;
1026 klass->get_guest_username = display_real_get_guest_username;
1027 klass->create_session = display_create_session;
1028 object_class->finalize = display_finalize;
1030 g_type_class_add_private (klass, sizeof (DisplayPrivate));
1033 g_signal_new ("started",
1034 G_TYPE_FROM_CLASS (klass),
1036 G_STRUCT_OFFSET (DisplayClass, started),
1038 g_cclosure_marshal_VOID__VOID,
1041 g_signal_new ("ready",
1042 G_TYPE_FROM_CLASS (klass),
1044 G_STRUCT_OFFSET (DisplayClass, ready),
1046 g_cclosure_marshal_VOID__VOID,
1048 signals[SWITCH_TO_USER] =
1049 g_signal_new ("switch-to-user",
1050 G_TYPE_FROM_CLASS (klass),
1052 G_STRUCT_OFFSET (DisplayClass, switch_to_user),
1053 g_signal_accumulator_true_handled,
1055 ldm_marshal_BOOLEAN__STRING,
1056 G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
1057 signals[SWITCH_TO_GUEST] =
1058 g_signal_new ("switch-to-guest",
1059 G_TYPE_FROM_CLASS (klass),
1061 G_STRUCT_OFFSET (DisplayClass, switch_to_guest),
1062 g_signal_accumulator_true_handled,
1064 ldm_marshal_BOOLEAN__VOID,
1066 signals[GET_GUEST_USERNAME] =
1067 g_signal_new ("get-guest-username",
1068 G_TYPE_FROM_CLASS (klass),
1070 G_STRUCT_OFFSET (DisplayClass, get_guest_username),
1071 g_signal_accumulator_first_wins,
1073 ldm_marshal_STRING__VOID,
1075 signals[SESSION_STARTED] =
1076 g_signal_new ("session-started",
1077 G_TYPE_FROM_CLASS (klass),
1079 G_STRUCT_OFFSET (DisplayClass, session_started),
1081 g_cclosure_marshal_VOID__VOID,
1083 signals[SESSION_STOPPED] =
1084 g_signal_new ("session-stopped",
1085 G_TYPE_FROM_CLASS (klass),
1087 G_STRUCT_OFFSET (DisplayClass, session_stopped),
1089 g_cclosure_marshal_VOID__VOID,
1092 g_signal_new ("stopped",
1093 G_TYPE_FROM_CLASS (klass),
1095 G_STRUCT_OFFSET (DisplayClass, stopped),
1097 g_cclosure_marshal_VOID__VOID,