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
20 #include <glib/gstdio.h>
25 #include "configuration.h"
26 #include "console-kit.h"
28 #include "guest-account.h"
32 AUTHENTICATION_COMPLETE,
36 static guint signals[LAST_SIGNAL] = { 0 };
40 /* Display server running on */
41 DisplayServer *display_server;
43 /* PID of child process */
46 /* Pipes to talk to child */
48 int from_child_output;
49 GIOChannel *from_child_channel;
50 guint from_child_watch;
53 /* User to authenticate as */
56 /* TRUE if is a guest account */
59 /* User object that matches the current username */
62 /* PAM service to use */
65 /* TRUE if should run PAM authentication phase */
66 gboolean do_authenticate;
68 /* TRUE if can handle PAM prompts */
69 gboolean is_interactive;
71 /* Messages being requested by PAM */
73 struct pam_message *messages;
75 /* Authentication result from PAM */
76 gboolean authentication_started;
77 gboolean authentication_complete;
78 int authentication_result;
79 gchar *authentication_result_string;
87 /* tty this session is running on */
90 /* X display connected to */
92 XAuthority *x_authority;
93 gboolean x_authority_use_system_location;
95 /* Remote host this session is being controlled from */
96 gchar *remote_host_name;
98 /* Console kit cookie */
99 gchar *console_kit_cookie;
102 gchar *login1_session;
104 /* Environment to set in child */
107 /* Command to run in child */
110 /* True if have run command */
111 gboolean command_run;
113 /* TRUE if stopping this session */
117 /* Maximum length of a string to pass between daemon and session */
118 #define MAX_STRING_LENGTH 65535
120 G_DEFINE_TYPE (Session, session, G_TYPE_OBJECT);
125 return g_object_new (SESSION_TYPE, NULL);
129 session_set_pam_service (Session *session, const gchar *pam_service)
131 g_return_if_fail (session != NULL);
132 g_free (session->priv->pam_service);
133 session->priv->pam_service = g_strdup (pam_service);
137 session_set_username (Session *session, const gchar *username)
139 g_return_if_fail (session != NULL);
140 g_free (session->priv->username);
141 session->priv->username = g_strdup (username);
145 session_set_do_authenticate (Session *session, gboolean do_authenticate)
147 g_return_if_fail (session != NULL);
148 session->priv->do_authenticate = do_authenticate;
152 session_set_is_interactive (Session *session, gboolean is_interactive)
154 g_return_if_fail (session != NULL);
155 session->priv->is_interactive = is_interactive;
159 session_set_is_guest (Session *session, gboolean is_guest)
161 g_return_if_fail (session != NULL);
162 session->priv->is_guest = is_guest;
166 session_get_is_guest (Session *session)
168 g_return_val_if_fail (session != NULL, FALSE);
169 return session->priv->is_guest;
173 session_set_log_file (Session *session, const gchar *filename)
175 g_return_if_fail (session != NULL);
176 g_free (session->priv->log_filename);
177 session->priv->log_filename = g_strdup (filename);
181 session_set_class (Session *session, const gchar *class)
183 g_return_if_fail (session != NULL);
184 g_free (session->priv->class);
185 session->priv->class = g_strdup (class);
189 session_set_display_server (Session *session, DisplayServer *display_server)
191 g_return_if_fail (session != NULL);
192 g_return_if_fail (display_server != NULL);
193 if (session->priv->display_server)
195 display_server_disconnect_session (session->priv->display_server, session);
196 g_object_unref (session->priv->display_server);
198 session->priv->display_server = g_object_ref (display_server);
202 session_get_display_server (Session *session)
204 g_return_val_if_fail (session != NULL, NULL);
205 return session->priv->display_server;
209 session_set_tty (Session *session, const gchar *tty)
211 g_return_if_fail (session != NULL);
212 g_free (session->priv->tty);
213 session->priv->tty = g_strdup (tty);
217 session_set_xdisplay (Session *session, const gchar *xdisplay)
219 g_return_if_fail (session != NULL);
220 g_free (session->priv->xdisplay);
221 session->priv->xdisplay = g_strdup (xdisplay);
225 session_set_x_authority (Session *session, XAuthority *authority, gboolean use_system_location)
227 g_return_if_fail (session != NULL);
228 if (session->priv->x_authority)
230 g_object_unref (session->priv->x_authority);
231 session->priv->x_authority = NULL;
234 session->priv->x_authority = g_object_ref (authority);
235 session->priv->x_authority_use_system_location = use_system_location;
239 session_set_remote_host_name (Session *session, const gchar *remote_host_name)
241 g_return_if_fail (session != NULL);
242 g_free (session->priv->remote_host_name);
243 session->priv->remote_host_name = g_strdup (remote_host_name);
247 find_env_entry (Session *session, const gchar *name)
251 for (link = session->priv->env; link; link = link->next)
253 const gchar *entry = link->data;
255 if (g_str_has_prefix (entry, name) && entry[strlen (name)] == '=')
263 session_set_env (Session *session, const gchar *name, const gchar *value)
268 g_return_if_fail (session != NULL);
269 g_return_if_fail (value != NULL);
271 entry = g_strdup_printf ("%s=%s", name, value);
273 link = find_env_entry (session, name);
280 session->priv->env = g_list_append (session->priv->env, entry);
284 session_unset_env (Session *session, const gchar *name)
288 g_return_if_fail (session != NULL);
290 link = find_env_entry (session, name);
295 session->priv->env = g_list_remove_link (session->priv->env, link);
299 session_set_argv (Session *session, gchar **argv)
301 g_return_if_fail (session != NULL);
302 session->priv->argv = g_strdupv (argv);
306 session_get_user (Session *session)
308 g_return_val_if_fail (session != NULL, NULL);
310 if (session->priv->username == NULL)
313 if (!session->priv->user)
314 session->priv->user = accounts_get_user_by_name (session->priv->username);
316 return session->priv->user;
320 write_data (Session *session, const void *buf, size_t count)
322 if (write (session->priv->to_child_input, buf, count) != count)
323 g_warning ("Error writing to session: %s", strerror (errno));
327 write_string (Session *session, const char *value)
331 length = value ? strlen (value) : -1;
332 write_data (session, &length, sizeof (length));
334 write_data (session, value, sizeof (char) * length);
338 write_xauth (Session *session, XAuthority *x_authority)
345 write_string (session, NULL);
349 write_string (session, x_authority_get_authorization_name (session->priv->x_authority));
350 family = x_authority_get_family (session->priv->x_authority);
351 write_data (session, &family, sizeof (family));
352 length = x_authority_get_address_length (session->priv->x_authority);
353 write_data (session, &length, sizeof (length));
354 write_data (session, x_authority_get_address (session->priv->x_authority), length);
355 write_string (session, x_authority_get_number (session->priv->x_authority));
356 length = x_authority_get_authorization_data_length (session->priv->x_authority);
357 write_data (session, &length, sizeof (length));
358 write_data (session, x_authority_get_authorization_data (session->priv->x_authority), length);
362 read_from_child (Session *session, void *buf, size_t count)
365 n_read = read (session->priv->from_child_output, buf, count);
367 g_warning ("Error reading from session: %s", strerror (errno));
372 read_string_from_child (Session *session)
377 if (read_from_child (session, &length, sizeof (length)) <= 0)
381 if (length > MAX_STRING_LENGTH)
383 g_warning ("Invalid string length %d from child", length);
387 value = g_malloc (sizeof (char) * (length + 1));
388 read_from_child (session, value, length);
389 value[length] = '\0';
395 session_watch_cb (GPid pid, gint status, gpointer data)
397 Session *session = data;
399 session->priv->pid = 0;
401 if (WIFEXITED (status))
402 g_debug ("Session %d exited with return value %d", pid, WEXITSTATUS (status));
403 else if (WIFSIGNALED (status))
404 g_debug ("Session %d terminated with signal %d", pid, WTERMSIG (status));
406 /* If failed during authentication then report this as an authentication failure */
407 if (session->priv->authentication_started && !session->priv->authentication_complete)
409 g_debug ("Session %d failed during authentication", pid);
410 session->priv->authentication_complete = TRUE;
411 session->priv->authentication_result = PAM_CONV_ERR;
412 g_free (session->priv->authentication_result_string);
413 session->priv->authentication_result_string = g_strdup ("Authentication stopped before completion");
414 g_signal_emit (G_OBJECT (session), signals[AUTHENTICATION_COMPLETE], 0);
417 g_signal_emit (G_OBJECT (session), signals[STOPPED], 0);
419 /* Delete account if it is a guest one */
420 if (session->priv->is_guest)
421 guest_account_cleanup (session->priv->username);
423 /* Drop our reference on the child process, it has terminated */
424 g_object_unref (session);
428 from_child_cb (GIOChannel *source, GIOCondition condition, gpointer data)
430 Session *session = data;
433 gboolean auth_complete;
435 /* Remote end gone */
436 if (condition == G_IO_HUP)
438 session->priv->from_child_watch = 0;
442 /* Get the username currently being authenticated (may change during authentication) */
443 username = read_string_from_child (session);
444 if (g_strcmp0 (username, session->priv->username) != 0)
446 g_free (session->priv->username);
447 session->priv->username = username;
448 if (session->priv->user)
449 g_object_unref (session->priv->user);
450 session->priv->user = NULL;
455 /* Check if authentication completed */
456 n_read = read_from_child (session, &auth_complete, sizeof (auth_complete));
458 g_debug ("Error reading from child: %s", strerror (errno));
461 session->priv->from_child_watch = 0;
467 session->priv->authentication_complete = TRUE;
468 read_from_child (session, &session->priv->authentication_result, sizeof (session->priv->authentication_result));
469 g_free (session->priv->authentication_result_string);
470 session->priv->authentication_result_string = read_string_from_child (session);
472 g_debug ("Session %d authentication complete with return value %d: %s", session->priv->pid, session->priv->authentication_result, session->priv->authentication_result_string);
474 /* No longer expect any more messages */
475 session->priv->from_child_watch = 0;
477 g_signal_emit (G_OBJECT (session), signals[AUTHENTICATION_COMPLETE], 0);
485 session->priv->messages_length = 0;
486 read_from_child (session, &session->priv->messages_length, sizeof (session->priv->messages_length));
487 session->priv->messages = calloc (session->priv->messages_length, sizeof (struct pam_message));
488 for (i = 0; i < session->priv->messages_length; i++)
490 struct pam_message *m = &session->priv->messages[i];
491 read_from_child (session, &m->msg_style, sizeof (m->msg_style));
492 m->msg = read_string_from_child (session);
495 g_debug ("Session %d got %d message(s) from PAM", session->priv->pid, session->priv->messages_length);
497 g_signal_emit (G_OBJECT (session), signals[GOT_MESSAGES], 0);
504 session_start (Session *session)
506 g_return_val_if_fail (session != NULL, FALSE);
507 g_return_val_if_fail (session->priv->display_server != NULL, FALSE);
508 return SESSION_GET_CLASS (session)->start (session);
512 session_get_is_started (Session *session)
514 return session->priv->pid != 0;
518 session_real_start (Session *session)
521 int to_child_pipe[2], from_child_pipe[2];
522 int to_child_output, from_child_input;
524 g_return_val_if_fail (session->priv->pid == 0, FALSE);
526 display_server_connect_session (session->priv->display_server, session);
528 /* Create pipes to talk to the child */
529 if (pipe (to_child_pipe) < 0 || pipe (from_child_pipe) < 0)
531 g_warning ("Failed to create pipe to communicate with session process: %s", strerror (errno));
534 to_child_output = to_child_pipe[0];
535 session->priv->to_child_input = to_child_pipe[1];
536 session->priv->from_child_output = from_child_pipe[0];
537 from_child_input = from_child_pipe[1];
538 session->priv->from_child_channel = g_io_channel_unix_new (session->priv->from_child_output);
539 session->priv->from_child_watch = g_io_add_watch (session->priv->from_child_channel, G_IO_IN | G_IO_HUP, from_child_cb, session);
541 /* Don't allow the daemon end of the pipes to be accessed in child processes */
542 fcntl (session->priv->to_child_input, F_SETFD, FD_CLOEXEC);
543 fcntl (session->priv->from_child_output, F_SETFD, FD_CLOEXEC);
545 /* Create the guest account if it is one */
546 if (session->priv->is_guest && session->priv->username == NULL)
548 session->priv->username = guest_account_setup ();
549 if (!session->priv->username)
554 session->priv->pid = fork ();
555 if (session->priv->pid < 0)
557 g_debug ("Failed to fork session child process: %s", strerror (errno));
561 if (session->priv->pid == 0)
563 /* Run us again in session child mode */
567 g_strdup_printf ("%d", to_child_output),
568 g_strdup_printf ("%d", from_child_input),
570 _exit (EXIT_FAILURE);
573 /* Hold a reference on this object until the child process terminates so we
574 * can handle the watch callback even if it is no longer used. Otherwise a
575 * zombie process will remain */
576 g_object_ref (session);
578 /* Listen for session termination */
579 session->priv->authentication_started = TRUE;
580 session->priv->child_watch = g_child_watch_add (session->priv->pid, session_watch_cb, session);
582 /* Close the ends of the pipes we don't need */
583 close (to_child_output);
584 close (from_child_input);
586 /* Indicate what version of the protocol we are using */
588 write_data (session, &version, sizeof (version));
590 /* Send configuration */
591 write_string (session, session->priv->pam_service);
592 write_string (session, session->priv->username);
593 write_data (session, &session->priv->do_authenticate, sizeof (session->priv->do_authenticate));
594 write_data (session, &session->priv->is_interactive, sizeof (session->priv->is_interactive));
595 write_string (session, session->priv->class);
596 write_string (session, session->priv->tty);
597 write_string (session, session->priv->remote_host_name);
598 write_string (session, session->priv->xdisplay);
599 write_xauth (session, session->priv->x_authority);
601 g_debug ("Started session %d with service '%s', username '%s'", session->priv->pid, session->priv->pam_service, session->priv->username);
607 session_get_username (Session *session)
609 g_return_val_if_fail (session != NULL, NULL);
610 return session->priv->username;
614 session_get_console_kit_cookie (Session *session)
616 g_return_val_if_fail (session != NULL, NULL);
617 return session->priv->console_kit_cookie;
621 session_respond (Session *session, struct pam_response *response)
623 int error = PAM_SUCCESS;
626 g_return_if_fail (session != NULL);
628 write_data (session, &error, sizeof (error));
629 for (i = 0; i < session->priv->messages_length; i++)
631 write_string (session, response[i].resp);
632 write_data (session, &response[i].resp_retcode, sizeof (response[i].resp_retcode));
635 /* Delete the old messages */
636 for (i = 0; i < session->priv->messages_length; i++)
637 g_free ((char *) session->priv->messages[i].msg);
638 g_free (session->priv->messages);
639 session->priv->messages = NULL;
640 session->priv->messages_length = 0;
644 session_respond_error (Session *session, int error)
646 g_return_if_fail (session != NULL);
647 g_return_if_fail (error != PAM_SUCCESS);
649 write_data (session, &error, sizeof (error));
653 session_get_messages_length (Session *session)
655 g_return_val_if_fail (session != NULL, 0);
656 return session->priv->messages_length;
659 const struct pam_message *
660 session_get_messages (Session *session)
662 g_return_val_if_fail (session != NULL, NULL);
663 return session->priv->messages;
667 session_get_is_authenticated (Session *session)
669 g_return_val_if_fail (session != NULL, FALSE);
670 return session->priv->authentication_complete && session->priv->authentication_result == PAM_SUCCESS;
674 session_get_authentication_result (Session *session)
676 g_return_val_if_fail (session != NULL, 0);
677 return session->priv->authentication_result;
681 session_get_authentication_result_string (Session *session)
683 g_return_val_if_fail (session != NULL, NULL);
684 return session->priv->authentication_result_string;
688 session_run (Session *session)
690 g_return_if_fail (session->priv->display_server != NULL);
691 return SESSION_GET_CLASS (session)->run (session);
695 session_real_run (Session *session)
698 gchar *command, *x_authority_filename;
701 g_return_if_fail (session != NULL);
702 g_return_if_fail (!session->priv->command_run);
703 g_return_if_fail (session_get_is_authenticated (session));
704 g_return_if_fail (session->priv->argv != NULL);
705 g_return_if_fail (session->priv->pid != 0);
707 display_server_connect_session (session->priv->display_server, session);
709 session->priv->command_run = TRUE;
711 command = g_strjoinv (" ", session->priv->argv);
712 g_debug ("Session %d running command %s", session->priv->pid, command);
715 /* Create authority location */
716 if (session->priv->x_authority_use_system_location)
718 gchar *run_dir, *dir;
720 run_dir = config_get_string (config_get_instance (), "LightDM", "run-directory");
721 dir = g_build_filename (run_dir, session->priv->username, NULL);
724 if (g_mkdir_with_parents (dir, S_IRWXU) < 0)
725 g_warning ("Failed to set create system authority dir %s: %s", dir, strerror (errno));
728 if (chown (dir, user_get_uid (session_get_user (session)), user_get_gid (session_get_user (session))) < 0)
729 g_warning ("Failed to set ownership of user authority dir: %s", strerror (errno));
732 x_authority_filename = g_build_filename (dir, "xauthority", NULL);
736 x_authority_filename = g_build_filename (user_get_home_directory (session_get_user (session)), ".Xauthority", NULL);
738 write_string (session, session->priv->log_filename);
739 write_string (session, session->priv->tty);
740 write_string (session, x_authority_filename);
741 g_free (x_authority_filename);
742 write_string (session, session->priv->xdisplay);
743 write_xauth (session, session->priv->x_authority);
744 argc = g_list_length (session->priv->env);
745 write_data (session, &argc, sizeof (argc));
746 for (link = session->priv->env; link; link = link->next)
747 write_string (session, (gchar *) link->data);
748 argc = g_strv_length (session->priv->argv);
749 write_data (session, &argc, sizeof (argc));
750 for (i = 0; i < argc; i++)
751 write_string (session, session->priv->argv[i]);
753 if (login1_is_running ())
754 session->priv->login1_session = read_string_from_child (session);
755 if (!session->priv->login1_session)
756 session->priv->console_kit_cookie = read_string_from_child (session);
760 session_lock (Session *session)
762 g_return_if_fail (session != NULL);
765 if (login1_is_running ())
766 login1_lock_session (session->priv->login1_session);
767 if (!session->priv->login1_session)
768 ck_lock_session (session->priv->console_kit_cookie);
773 session_unlock (Session *session)
775 g_return_if_fail (session != NULL);
778 if (login1_is_running ())
779 login1_unlock_session (session->priv->login1_session);
780 if (!session->priv->login1_session)
781 ck_unlock_session (session->priv->console_kit_cookie);
786 session_stop (Session *session)
788 g_return_if_fail (session != NULL);
790 if (session->priv->stopping)
792 session->priv->stopping = TRUE;
794 return SESSION_GET_CLASS (session)->stop (session);
798 session_real_stop (Session *session)
800 g_return_if_fail (session != NULL);
802 if (session->priv->pid > 0)
804 g_debug ("Session %d: Sending SIGTERM", session->priv->pid);
805 kill (session->priv->pid, SIGTERM);
806 // FIXME: Handle timeout
809 g_signal_emit (G_OBJECT (session), signals[STOPPED], 0);
813 session_get_is_stopping (Session *session)
815 g_return_val_if_fail (session != NULL, FALSE);
816 return session->priv->stopping;
820 session_init (Session *session)
822 session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, SESSION_TYPE, SessionPrivate);
823 session->priv->log_filename = g_strdup (".xsession-errors");
827 session_finalize (GObject *object)
829 Session *self = SESSION (object);
832 if (self->priv->display_server)
833 g_object_unref (self->priv->display_server);
835 kill (self->priv->pid, SIGKILL);
836 if (self->priv->from_child_channel)
837 g_io_channel_unref (self->priv->from_child_channel);
838 if (self->priv->from_child_watch)
839 g_source_remove (self->priv->from_child_watch);
840 if (self->priv->child_watch)
841 g_source_remove (self->priv->child_watch);
842 g_free (self->priv->username);
843 if (self->priv->user)
844 g_object_unref (self->priv->user);
845 g_free (self->priv->pam_service);
846 for (i = 0; i < self->priv->messages_length; i++)
847 g_free ((char *) self->priv->messages[i].msg);
848 g_free (self->priv->messages);
849 g_free (self->priv->authentication_result_string);
850 g_free (self->priv->log_filename);
851 g_free (self->priv->class);
852 g_free (self->priv->tty);
853 g_free (self->priv->xdisplay);
854 if (self->priv->x_authority)
855 g_object_unref (self->priv->x_authority);
856 g_free (self->priv->remote_host_name);
857 g_free (self->priv->login1_session);
858 g_free (self->priv->console_kit_cookie);
859 g_list_free_full (self->priv->env, g_free);
860 g_strfreev (self->priv->argv);
862 G_OBJECT_CLASS (session_parent_class)->finalize (object);
866 session_class_init (SessionClass *klass)
868 GObjectClass *object_class = G_OBJECT_CLASS (klass);
870 klass->start = session_real_start;
871 klass->run = session_real_run;
872 klass->stop = session_real_stop;
873 object_class->finalize = session_finalize;
875 g_type_class_add_private (klass, sizeof (SessionPrivate));
877 signals[GOT_MESSAGES] =
878 g_signal_new ("got-messages",
879 G_TYPE_FROM_CLASS (klass),
881 G_STRUCT_OFFSET (SessionClass, got_messages),
886 signals[AUTHENTICATION_COMPLETE] =
887 g_signal_new ("authentication-complete",
888 G_TYPE_FROM_CLASS (klass),
890 G_STRUCT_OFFSET (SessionClass, authentication_complete),
896 g_signal_new ("stopped",
897 G_TYPE_FROM_CLASS (klass),
899 G_STRUCT_OFFSET (SessionClass, stopped),