1 /*
2  * Copyright (C) 2010-2011 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  *
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
9  * license.
10  */
11 
12 #include <config.h>
13 
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <sys/wait.h>
19 #include <fcntl.h>
20 #include <glib/gstdio.h>
21 #include <grp.h>
22 #include <pwd.h>
23 
24 #include "session.h"
25 #include "configuration.h"
26 #include "console-kit.h"
27 #include "login1.h"
28 #include "guest-account.h"
29 #include "shared-data-manager.h"
30 #include "greeter-socket.h"
31 
32 enum {
33     CREATE_GREETER,
34     GOT_MESSAGES,
35     AUTHENTICATION_COMPLETE,
36     STOPPED,
37     LAST_SIGNAL
38 };
39 static guint signals[LAST_SIGNAL] = { 0 };
40 
41 typedef struct
42 {
43     /* Configuration for this session */
44     SessionConfig *config;
45 
46     /* Display server running on */
47     DisplayServer *display_server;
48 
49     /* PID of child process */
50     GPid pid;
51 
52     /* Pipes to talk to child */
53     int to_child_input;
54     int from_child_output;
55     GIOChannel *from_child_channel;
56     guint from_child_watch;
57     guint child_watch;
58 
59     /* User to authenticate as */
60     gchar *username;
61 
62     /* TRUE if is a guest account */
63     gboolean is_guest;
64 
65     /* User object that matches the current username */
66     User *user;
67 
68     /* PAM service to use */
69     gchar *pam_service;
70 
71     /* TRUE if should run PAM authentication phase */
72     gboolean do_authenticate;
73 
74     /* TRUE if can handle PAM prompts */
75     gboolean is_interactive;
76 
77     /* Messages being requested by PAM */
78     int messages_length;
79     struct pam_message *messages;
80 
81     /* Authentication result from PAM */
82     gboolean authentication_started;
83     gboolean authentication_complete;
84     int authentication_result;
85     gchar *authentication_result_string;
86 
87     /* File to log to */
88     gchar *log_filename;
89     LogMode log_mode;
90 
91     /* tty this session is running on */
92     gchar *tty;
93 
94     /* X display connected to */
95     gchar *xdisplay;
96     XAuthority *x_authority;
97     gboolean x_authority_use_system_location;
98 
99     /* Socket to allow greeters to connect to (if allowed) */
100     GreeterSocket *greeter_socket;
101 
102     /* Remote host this session is being controlled from */
103     gchar *remote_host_name;
104 
105     /* Console kit cookie */
106     gchar *console_kit_cookie;
107 
108     /* login1 session ID */
109     gchar *login1_session_id;
110 
111     /* Environment to set in child */
112     GList *env;
113 
114     /* Command to run in child */
115     gchar **argv;
116 
117     /* True if have run command */
118     gboolean command_run;
119 
120     /* TRUE if stopping this session */
121     gboolean stopping;
122 } SessionPrivate;
123 
124 /* Maximum length of a string to pass between daemon and session */
125 #define MAX_STRING_LENGTH 65535
126 
127 static void session_logger_iface_init (LoggerInterface *iface);
128 
G_DEFINE_TYPE_WITH_CODE(Session,session,G_TYPE_OBJECT,G_ADD_PRIVATE (Session)G_IMPLEMENT_INTERFACE (LOGGER_TYPE,session_logger_iface_init))129 G_DEFINE_TYPE_WITH_CODE (Session, session, G_TYPE_OBJECT,
130                          G_ADD_PRIVATE (Session)
131                          G_IMPLEMENT_INTERFACE (
132                              LOGGER_TYPE, session_logger_iface_init))
133 
134 Session *
135 session_new (void)
136 {
137     return g_object_new (SESSION_TYPE, NULL);
138 }
139 
140 void
session_set_config(Session * session,SessionConfig * config)141 session_set_config (Session *session, SessionConfig *config)
142 {
143     SessionPrivate *priv = session_get_instance_private (session);
144 
145     g_return_if_fail (session != NULL);
146 
147     g_clear_object (&priv->config);
148     priv->config = g_object_ref (config);
149 }
150 
151 SessionConfig *
session_get_config(Session * session)152 session_get_config (Session *session)
153 {
154     SessionPrivate *priv = session_get_instance_private (session);
155     g_return_val_if_fail (session != NULL, NULL);
156     return priv->config;
157 }
158 
159 const gchar *
session_get_session_type(Session * session)160 session_get_session_type (Session *session)
161 {
162     SessionPrivate *priv = session_get_instance_private (session);
163     g_return_val_if_fail (session != NULL, NULL);
164     return session_config_get_session_type (priv->config);
165 }
166 
167 void
session_set_pam_service(Session * session,const gchar * pam_service)168 session_set_pam_service (Session *session, const gchar *pam_service)
169 {
170     SessionPrivate *priv = session_get_instance_private (session);
171     g_return_if_fail (session != NULL);
172     g_free (priv->pam_service);
173     priv->pam_service = g_strdup (pam_service);
174 }
175 
176 void
session_set_username(Session * session,const gchar * username)177 session_set_username (Session *session, const gchar *username)
178 {
179     SessionPrivate *priv = session_get_instance_private (session);
180     g_return_if_fail (session != NULL);
181     g_free (priv->username);
182     priv->username = g_strdup (username);
183 }
184 
185 void
session_set_do_authenticate(Session * session,gboolean do_authenticate)186 session_set_do_authenticate (Session *session, gboolean do_authenticate)
187 {
188     SessionPrivate *priv = session_get_instance_private (session);
189     g_return_if_fail (session != NULL);
190     priv->do_authenticate = do_authenticate;
191 }
192 
193 void
session_set_is_interactive(Session * session,gboolean is_interactive)194 session_set_is_interactive (Session *session, gboolean is_interactive)
195 {
196     SessionPrivate *priv = session_get_instance_private (session);
197     g_return_if_fail (session != NULL);
198     priv->is_interactive = is_interactive;
199 }
200 
201 void
session_set_is_guest(Session * session,gboolean is_guest)202 session_set_is_guest (Session *session, gboolean is_guest)
203 {
204     SessionPrivate *priv = session_get_instance_private (session);
205     g_return_if_fail (session != NULL);
206     priv->is_guest = is_guest;
207 }
208 
209 gboolean
session_get_is_guest(Session * session)210 session_get_is_guest (Session *session)
211 {
212     SessionPrivate *priv = session_get_instance_private (session);
213     g_return_val_if_fail (session != NULL, FALSE);
214     return priv->is_guest;
215 }
216 
217 void
session_set_log_file(Session * session,const gchar * filename,LogMode log_mode)218 session_set_log_file (Session *session, const gchar *filename, LogMode log_mode)
219 {
220     SessionPrivate *priv = session_get_instance_private (session);
221     g_return_if_fail (session != NULL);
222     g_free (priv->log_filename);
223     priv->log_filename = g_strdup (filename);
224     priv->log_mode = log_mode;
225 }
226 
227 void
session_set_display_server(Session * session,DisplayServer * display_server)228 session_set_display_server (Session *session, DisplayServer *display_server)
229 {
230     SessionPrivate *priv = session_get_instance_private (session);
231 
232     g_return_if_fail (session != NULL);
233     g_return_if_fail (display_server != NULL);
234 
235     if (priv->display_server == display_server)
236         return;
237 
238     if (priv->display_server)
239         display_server_disconnect_session (priv->display_server, session);
240     g_clear_object (&priv->display_server);
241     priv->display_server = g_object_ref (display_server);
242 }
243 
244 DisplayServer *
session_get_display_server(Session * session)245 session_get_display_server (Session *session)
246 {
247     SessionPrivate *priv = session_get_instance_private (session);
248     g_return_val_if_fail (session != NULL, NULL);
249     return priv->display_server;
250 }
251 
252 void
session_set_tty(Session * session,const gchar * tty)253 session_set_tty (Session *session, const gchar *tty)
254 {
255     SessionPrivate *priv = session_get_instance_private (session);
256     g_return_if_fail (session != NULL);
257     g_free (priv->tty);
258     priv->tty = g_strdup (tty);
259 }
260 
261 void
session_set_xdisplay(Session * session,const gchar * xdisplay)262 session_set_xdisplay (Session *session, const gchar *xdisplay)
263 {
264     SessionPrivate *priv = session_get_instance_private (session);
265     g_return_if_fail (session != NULL);
266     g_free (priv->xdisplay);
267     priv->xdisplay = g_strdup (xdisplay);
268 }
269 
270 void
session_set_x_authority(Session * session,XAuthority * authority,gboolean use_system_location)271 session_set_x_authority (Session *session, XAuthority *authority, gboolean use_system_location)
272 {
273     SessionPrivate *priv = session_get_instance_private (session);
274     g_return_if_fail (session != NULL);
275     g_clear_object (&priv->x_authority);
276     if (authority)
277         priv->x_authority = g_object_ref (authority);
278     priv->x_authority_use_system_location = use_system_location;
279 }
280 
281 void
session_set_remote_host_name(Session * session,const gchar * remote_host_name)282 session_set_remote_host_name (Session *session, const gchar *remote_host_name)
283 {
284     SessionPrivate *priv = session_get_instance_private (session);
285     g_return_if_fail (session != NULL);
286     g_free (priv->remote_host_name);
287     priv->remote_host_name = g_strdup (remote_host_name);
288 }
289 
290 static GList *
find_env_entry(Session * session,const gchar * name)291 find_env_entry (Session *session, const gchar *name)
292 {
293     SessionPrivate *priv = session_get_instance_private (session);
294 
295     for (GList *link = priv->env; link; link = link->next)
296     {
297         const gchar *entry = link->data;
298 
299         if (g_str_has_prefix (entry, name) && entry[strlen (name)] == '=')
300             return link;
301     }
302 
303     return NULL;
304 }
305 
306 void
session_set_env(Session * session,const gchar * name,const gchar * value)307 session_set_env (Session *session, const gchar *name, const gchar *value)
308 {
309     SessionPrivate *priv = session_get_instance_private (session);
310 
311     g_return_if_fail (session != NULL);
312     g_return_if_fail (value != NULL);
313 
314     gchar *entry = g_strdup_printf ("%s=%s", name, value);
315 
316     GList *link = find_env_entry (session, name);
317     if (link)
318     {
319         g_free (link->data);
320         link->data = entry;
321     }
322     else
323         priv->env = g_list_append (priv->env, entry);
324 }
325 
326 const gchar *
session_get_env(Session * session,const gchar * name)327 session_get_env (Session *session, const gchar *name)
328 {
329     GList *link = find_env_entry (session, name);
330     if (!link)
331         return NULL;
332 
333     gchar *entry = link->data;
334 
335     return entry + strlen (name) + 1;
336 }
337 
338 void
session_unset_env(Session * session,const gchar * name)339 session_unset_env (Session *session, const gchar *name)
340 {
341     SessionPrivate *priv = session_get_instance_private (session);
342 
343     g_return_if_fail (session != NULL);
344 
345     GList *link = find_env_entry (session, name);
346     if (!link)
347         return;
348 
349     g_free (link->data);
350     priv->env = g_list_delete_link (priv->env, link);
351 }
352 
353 void
session_set_argv(Session * session,gchar ** argv)354 session_set_argv (Session *session, gchar **argv)
355 {
356     SessionPrivate *priv = session_get_instance_private (session);
357     g_return_if_fail (session != NULL);
358     priv->argv = g_strdupv (argv);
359 }
360 
361 User *
session_get_user(Session * session)362 session_get_user (Session *session)
363 {
364     SessionPrivate *priv = session_get_instance_private (session);
365 
366     g_return_val_if_fail (session != NULL, NULL);
367 
368     if (priv->username == NULL)
369         return NULL;
370 
371     if (!priv->user)
372         priv->user = accounts_get_user_by_name (priv->username);
373 
374     return priv->user;
375 }
376 
377 static void
write_data(Session * session,const void * buf,size_t count)378 write_data (Session *session, const void *buf, size_t count)
379 {
380     SessionPrivate *priv = session_get_instance_private (session);
381     if (write (priv->to_child_input, buf, count) != count)
382         l_warning (session, "Error writing to session: %s", strerror (errno));
383 }
384 
385 static void
write_string(Session * session,const char * value)386 write_string (Session *session, const char *value)
387 {
388     int length = value ? strlen (value) : -1;
389     write_data (session, &length, sizeof (length));
390     if (value)
391         write_data (session, value, sizeof (char) * length);
392 }
393 
394 static void
write_xauth(Session * session,XAuthority * x_authority)395 write_xauth (Session *session, XAuthority *x_authority)
396 {
397     SessionPrivate *priv = session_get_instance_private (session);
398 
399     if (!x_authority)
400     {
401         write_string (session, NULL);
402         return;
403     }
404 
405     write_string (session, x_authority_get_authorization_name (priv->x_authority));
406     guint16 family = x_authority_get_family (priv->x_authority);
407     write_data (session, &family, sizeof (family));
408     gsize length = x_authority_get_address_length (priv->x_authority);
409     write_data (session, &length, sizeof (length));
410     write_data (session, x_authority_get_address (priv->x_authority), length);
411     write_string (session, x_authority_get_number (priv->x_authority));
412     length = x_authority_get_authorization_data_length (priv->x_authority);
413     write_data (session, &length, sizeof (length));
414     write_data (session, x_authority_get_authorization_data (priv->x_authority), length);
415 }
416 
417 static ssize_t
read_from_child(Session * session,void * buf,size_t count)418 read_from_child (Session *session, void *buf, size_t count)
419 {
420     SessionPrivate *priv = session_get_instance_private (session);
421 
422     ssize_t n_read = read (priv->from_child_output, buf, count);
423     if (n_read < 0)
424         l_warning (session, "Error reading from session: %s", strerror (errno));
425     return n_read;
426 }
427 
428 static gchar *
read_string_from_child(Session * session)429 read_string_from_child (Session *session)
430 {
431     int length;
432     if (read_from_child (session, &length, sizeof (length)) <= 0)
433         return NULL;
434     if (length < 0)
435         return NULL;
436     if (length > MAX_STRING_LENGTH)
437     {
438         l_warning (session, "Invalid string length %d from child", length);
439         return NULL;
440     }
441 
442     char *value = g_malloc (sizeof (char) * (length + 1));
443     read_from_child (session, value, length);
444     value[length] = '\0';
445 
446     return value;
447 }
448 
449 static void
session_watch_cb(GPid pid,gint status,gpointer data)450 session_watch_cb (GPid pid, gint status, gpointer data)
451 {
452     Session *session = data;
453     SessionPrivate *priv = session_get_instance_private (session);
454 
455     priv->child_watch = 0;
456 
457     if (WIFEXITED (status))
458         l_debug (session, "Exited with return value %d", WEXITSTATUS (status));
459     else if (WIFSIGNALED (status))
460         l_debug (session, "Terminated with signal %d", WTERMSIG (status));
461 
462     /* do this as late as possible for log messages prefix */
463     priv->pid = 0;
464 
465     /* If failed during authentication then report this as an authentication failure */
466     if (priv->authentication_started && !priv->authentication_complete)
467     {
468         l_debug (session, "Failed during authentication");
469         priv->authentication_complete = TRUE;
470         priv->authentication_result = PAM_CONV_ERR;
471         g_free (priv->authentication_result_string);
472         priv->authentication_result_string = g_strdup ("Authentication stopped before completion");
473         g_signal_emit (G_OBJECT (session), signals[AUTHENTICATION_COMPLETE], 0);
474     }
475 
476     g_signal_emit (G_OBJECT (session), signals[STOPPED], 0);
477 
478     /* Delete account if it is a guest one */
479     if (priv->is_guest)
480         guest_account_cleanup (priv->username);
481 
482     /* Drop our reference on the child process, it has terminated */
483     g_object_unref (session);
484 }
485 
486 static gboolean
from_child_cb(GIOChannel * source,GIOCondition condition,gpointer data)487 from_child_cb (GIOChannel *source, GIOCondition condition, gpointer data)
488 {
489     Session *session = data;
490     SessionPrivate *priv = session_get_instance_private (session);
491 
492     /* Remote end gone */
493     if (condition == G_IO_HUP)
494     {
495         priv->from_child_watch = 0;
496         return FALSE;
497     }
498 
499     /* Get the username currently being authenticated (may change during authentication) */
500     g_autofree gchar *username = read_string_from_child (session);
501     if (g_strcmp0 (username, priv->username) != 0)
502     {
503         g_free (priv->username);
504         priv->username = g_steal_pointer (&username);
505         g_clear_object (&priv->user);
506     }
507 
508     /* Check if authentication completed */
509     gboolean auth_complete;
510     ssize_t n_read = read_from_child (session, &auth_complete, sizeof (auth_complete));
511     if (n_read < 0)
512         l_debug (session, "Error reading from child: %s", strerror (errno));
513     if (n_read <= 0)
514     {
515         priv->from_child_watch = 0;
516         return FALSE;
517     }
518 
519     if (auth_complete)
520     {
521         priv->authentication_complete = TRUE;
522         read_from_child (session, &priv->authentication_result, sizeof (priv->authentication_result));
523         g_free (priv->authentication_result_string);
524         priv->authentication_result_string = read_string_from_child (session);
525 
526         l_debug (session, "Authentication complete with return value %d: %s", priv->authentication_result, priv->authentication_result_string);
527 
528         /* No longer expect any more messages */
529         priv->from_child_watch = 0;
530 
531         g_signal_emit (G_OBJECT (session), signals[AUTHENTICATION_COMPLETE], 0);
532 
533         return FALSE;
534     }
535     else
536     {
537         priv->messages_length = 0;
538         read_from_child (session, &priv->messages_length, sizeof (priv->messages_length));
539         priv->messages = calloc (priv->messages_length, sizeof (struct pam_message));
540         for (int i = 0; i < priv->messages_length; i++)
541         {
542             struct pam_message *m = &priv->messages[i];
543             read_from_child (session, &m->msg_style, sizeof (m->msg_style));
544             m->msg = read_string_from_child (session);
545         }
546 
547         l_debug (session, "Got %d message(s) from PAM", priv->messages_length);
548 
549         g_signal_emit (G_OBJECT (session), signals[GOT_MESSAGES], 0);
550     }
551 
552     return TRUE;
553 }
554 
555 gboolean
session_start(Session * session)556 session_start (Session *session)
557 {
558     g_return_val_if_fail (session != NULL, FALSE);
559     return SESSION_GET_CLASS (session)->start (session);
560 }
561 
562 gboolean
session_get_is_started(Session * session)563 session_get_is_started (Session *session)
564 {
565     SessionPrivate *priv = session_get_instance_private (session);
566     return priv->pid != 0;
567 }
568 
569 static Greeter *
create_greeter_cb(GreeterSocket * socket,Session * session)570 create_greeter_cb (GreeterSocket *socket, Session *session)
571 {
572     Greeter *greeter = NULL;
573     g_signal_emit (session, signals[CREATE_GREETER], 0, &greeter);
574     return greeter;
575 }
576 
577 static gboolean
session_real_start(Session * session)578 session_real_start (Session *session)
579 {
580     SessionPrivate *priv = session_get_instance_private (session);
581 
582     g_return_val_if_fail (priv->pid == 0, FALSE);
583 
584     if (priv->display_server)
585         display_server_connect_session (priv->display_server, session);
586 
587     /* Create pipes to talk to the child */
588     int to_child_pipe[2], from_child_pipe[2];
589     if (pipe (to_child_pipe) < 0 || pipe (from_child_pipe) < 0)
590     {
591         g_warning ("Failed to create pipe to communicate with session process: %s", strerror (errno));
592         return FALSE;
593     }
594     int to_child_output = to_child_pipe[0];
595     priv->to_child_input = to_child_pipe[1];
596     priv->from_child_output = from_child_pipe[0];
597     int from_child_input = from_child_pipe[1];
598     priv->from_child_channel = g_io_channel_unix_new (priv->from_child_output);
599     priv->from_child_watch = g_io_add_watch (priv->from_child_channel, G_IO_IN | G_IO_HUP, from_child_cb, session);
600 
601     /* Don't allow the daemon end of the pipes to be accessed in child processes */
602     fcntl (priv->to_child_input, F_SETFD, FD_CLOEXEC);
603     fcntl (priv->from_child_output, F_SETFD, FD_CLOEXEC);
604 
605     /* Create the guest account if it is one */
606     if (priv->is_guest && priv->username == NULL)
607     {
608         priv->username = guest_account_setup ();
609         if (!priv->username)
610             return FALSE;
611     }
612 
613     /* Run the child */
614     g_autofree gchar *arg0 = g_strdup_printf ("%d", to_child_output);
615     g_autofree gchar *arg1 = g_strdup_printf ("%d", from_child_input);
616     priv->pid = fork ();
617     if (priv->pid == 0)
618     {
619         /* Run us again in session child mode */
620         execlp ("lightdm",
621                 "lightdm",
622                 "--session-child",
623                 arg0, arg1, NULL);
624         _exit (EXIT_FAILURE);
625     }
626 
627     if (priv->pid < 0)
628     {
629         g_debug ("Failed to fork session child process: %s", strerror (errno));
630         return FALSE;
631     }
632 
633     /* Hold a reference on this object until the child process terminates so we
634      * can handle the watch callback even if it is no longer used. Otherwise a
635      * zombie process will remain */
636     g_object_ref (session);
637 
638     /* Listen for session termination */
639     priv->authentication_started = TRUE;
640     priv->child_watch = g_child_watch_add (priv->pid, session_watch_cb, session);
641 
642     /* Close the ends of the pipes we don't need */
643     close (to_child_output);
644     close (from_child_input);
645 
646     /* Indicate what version of the protocol we are using */
647     int version = 3;
648     write_data (session, &version, sizeof (version));
649 
650     /* Send configuration */
651     write_string (session, priv->pam_service);
652     write_string (session, priv->username);
653     write_data (session, &priv->do_authenticate, sizeof (priv->do_authenticate));
654     write_data (session, &priv->is_interactive, sizeof (priv->is_interactive));
655     write_string (session, NULL); /* Used to be class, now we just use the environment variable */
656     write_string (session, priv->tty);
657     write_string (session, priv->remote_host_name);
658     write_string (session, priv->xdisplay);
659     write_xauth (session, priv->x_authority);
660 
661     l_debug (session, "Started with service '%s', username '%s'", priv->pam_service, priv->username);
662 
663     return TRUE;
664 }
665 
666 const gchar *
session_get_username(Session * session)667 session_get_username (Session *session)
668 {
669     SessionPrivate *priv = session_get_instance_private (session);
670     g_return_val_if_fail (session != NULL, NULL);
671     return priv->username;
672 }
673 
674 const gchar *
session_get_login1_session_id(Session * session)675 session_get_login1_session_id (Session *session)
676 {
677     SessionPrivate *priv = session_get_instance_private (session);
678     g_return_val_if_fail (session != NULL, NULL);
679     return priv->login1_session_id;
680 }
681 
682 const gchar *
session_get_console_kit_cookie(Session * session)683 session_get_console_kit_cookie (Session *session)
684 {
685     SessionPrivate *priv = session_get_instance_private (session);
686     g_return_val_if_fail (session != NULL, NULL);
687     return priv->console_kit_cookie;
688 }
689 
690 void
session_respond(Session * session,struct pam_response * response)691 session_respond (Session *session, struct pam_response *response)
692 {
693     SessionPrivate *priv = session_get_instance_private (session);
694 
695     g_return_if_fail (session != NULL);
696 
697     int error = PAM_SUCCESS;
698     write_data (session, &error, sizeof (error));
699     for (int i = 0; i < priv->messages_length; i++)
700     {
701         write_string (session, response[i].resp);
702         write_data (session, &response[i].resp_retcode, sizeof (response[i].resp_retcode));
703     }
704 
705     /* Delete the old messages */
706     for (int i = 0; i < priv->messages_length; i++)
707         g_free ((char *) priv->messages[i].msg);
708     g_free (priv->messages);
709     priv->messages = NULL;
710     priv->messages_length = 0;
711 }
712 
713 void
session_respond_error(Session * session,int error)714 session_respond_error (Session *session, int error)
715 {
716     g_return_if_fail (session != NULL);
717     g_return_if_fail (error != PAM_SUCCESS);
718 
719     write_data (session, &error, sizeof (error));
720 }
721 
722 int
session_get_messages_length(Session * session)723 session_get_messages_length (Session *session)
724 {
725     SessionPrivate *priv = session_get_instance_private (session);
726     g_return_val_if_fail (session != NULL, 0);
727     return priv->messages_length;
728 }
729 
730 const struct pam_message *
session_get_messages(Session * session)731 session_get_messages (Session *session)
732 {
733     SessionPrivate *priv = session_get_instance_private (session);
734     g_return_val_if_fail (session != NULL, NULL);
735     return priv->messages;
736 }
737 
738 gboolean
session_get_is_authenticated(Session * session)739 session_get_is_authenticated (Session *session)
740 {
741     SessionPrivate *priv = session_get_instance_private (session);
742     g_return_val_if_fail (session != NULL, FALSE);
743     return priv->authentication_complete && priv->authentication_result == PAM_SUCCESS;
744 }
745 
746 int
session_get_authentication_result(Session * session)747 session_get_authentication_result (Session *session)
748 {
749     SessionPrivate *priv = session_get_instance_private (session);
750     g_return_val_if_fail (session != NULL, 0);
751     return priv->authentication_result;
752 }
753 
754 const gchar *
session_get_authentication_result_string(Session * session)755 session_get_authentication_result_string (Session *session)
756 {
757     SessionPrivate *priv = session_get_instance_private (session);
758     g_return_val_if_fail (session != NULL, NULL);
759     return priv->authentication_result_string;
760 }
761 
762 void
session_run(Session * session)763 session_run (Session *session)
764 {
765     SessionPrivate *priv = session_get_instance_private (session);
766     g_return_if_fail (session != NULL);
767     g_return_if_fail (priv->display_server != NULL);
768     return SESSION_GET_CLASS (session)->run (session);
769 }
770 
771 gboolean
session_get_is_run(Session * session)772 session_get_is_run (Session *session)
773 {
774     SessionPrivate *priv = session_get_instance_private (session);
775     g_return_val_if_fail (session != NULL, FALSE);
776     return priv->command_run;
777 }
778 
779 static void
session_real_run(Session * session)780 session_real_run (Session *session)
781 {
782     SessionPrivate *priv = session_get_instance_private (session);
783 
784     g_return_if_fail (session != NULL);
785     g_return_if_fail (!priv->command_run);
786     g_return_if_fail (session_get_is_authenticated (session));
787     g_return_if_fail (priv->argv != NULL);
788     g_return_if_fail (priv->pid != 0);
789 
790     display_server_connect_session (priv->display_server, session);
791 
792     priv->command_run = TRUE;
793 
794     g_autofree gchar *command = g_strjoinv (" ", priv->argv);
795     l_debug (session, "Running command %s", command);
796 
797     /* Create authority location */
798     g_autofree gchar *x_authority_filename = NULL;
799     if (priv->x_authority_use_system_location)
800     {
801         g_autofree gchar *run_dir = config_get_string (config_get_instance (), "LightDM", "run-directory");
802         g_autofree gchar *dir = g_build_filename (run_dir, priv->username, NULL);
803 
804         if (g_mkdir_with_parents (dir, S_IRWXU) < 0)
805             l_warning (session, "Failed to set create system authority dir %s: %s", dir, strerror (errno));
806         if (getuid () == 0)
807         {
808             if (chown (dir, user_get_uid (session_get_user (session)), user_get_gid (session_get_user (session))) < 0)
809                 l_warning (session, "Failed to set ownership of user authority dir: %s", strerror (errno));
810         }
811 
812         x_authority_filename = g_build_filename (dir, "xauthority", NULL);
813     }
814     else
815         x_authority_filename = g_build_filename (user_get_home_directory (session_get_user (session)), ".Xauthority", NULL);
816 
817     /* Make sure shared user directory for this user exists */
818     if (!priv->remote_host_name)
819     {
820         g_autofree gchar *data_dir = shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), priv->username);
821         if (data_dir)
822             session_set_env (session, "XDG_GREETER_DATA_DIR", data_dir);
823     }
824 
825     /* Open socket to allow in-session greeter */
826     if (priv->config && session_config_get_allow_greeter (priv->config))
827     {
828         g_autofree gchar *run_dir = config_get_string (config_get_instance (), "LightDM", "run-directory");
829         g_autofree gchar *dir = g_build_filename (run_dir, priv->username, NULL);
830 
831         if (g_mkdir_with_parents (dir, S_IRWXU) < 0)
832             l_warning (session, "Failed to create greeter socket dir %s: %s", dir, strerror (errno));
833         if (getuid () == 0)
834         {
835             if (chown (dir, user_get_uid (session_get_user (session)), user_get_gid (session_get_user (session))) < 0)
836                 l_warning (session, "Failed to set ownership of greeter socket dir: %s", strerror (errno));
837         }
838 
839         g_autofree gchar *path = g_build_filename (dir, "greeter-socket", NULL);
840         priv->greeter_socket = greeter_socket_new (path);
841         g_signal_connect (priv->greeter_socket, GREETER_SOCKET_SIGNAL_CREATE_GREETER, G_CALLBACK (create_greeter_cb), session);
842         session_set_env (session, "LIGHTDM_GREETER_PIPE", path);
843 
844         g_autoptr(GError) error = NULL;
845         if (!greeter_socket_start (priv->greeter_socket, &error))
846             l_warning (session, "Failed to start greeter socket: %s\n", error->message);
847     }
848 
849     if (priv->log_filename)
850         l_debug (session, "Logging to %s", priv->log_filename);
851     write_string (session, priv->log_filename);
852     write_data (session, &priv->log_mode, sizeof (priv->log_mode));
853     write_string (session, priv->tty);
854     write_string (session, x_authority_filename);
855     write_string (session, priv->xdisplay);
856     write_xauth (session, priv->x_authority);
857     gsize argc = g_list_length (priv->env);
858     write_data (session, &argc, sizeof (argc));
859     for (GList *link = priv->env; link; link = link->next)
860         write_string (session, (gchar *) link->data);
861     argc = g_strv_length (priv->argv);
862     write_data (session, &argc, sizeof (argc));
863     for (gsize i = 0; i < argc; i++)
864         write_string (session, priv->argv[i]);
865 
866     priv->login1_session_id = read_string_from_child (session);
867     priv->console_kit_cookie = read_string_from_child (session);
868 }
869 
870 void
session_lock(Session * session)871 session_lock (Session *session)
872 {
873     SessionPrivate *priv = session_get_instance_private (session);
874 
875     g_return_if_fail (session != NULL);
876 
877     if (getuid () == 0)
878     {
879         if (priv->login1_session_id)
880             login1_service_lock_session (login1_service_get_instance (), priv->login1_session_id);
881         else if (priv->console_kit_cookie)
882             ck_lock_session (priv->console_kit_cookie);
883     }
884 }
885 
886 void
session_unlock(Session * session)887 session_unlock (Session *session)
888 {
889     SessionPrivate *priv = session_get_instance_private (session);
890 
891     g_return_if_fail (session != NULL);
892 
893     if (getuid () == 0)
894     {
895         if (priv->login1_session_id)
896             login1_service_unlock_session (login1_service_get_instance (), priv->login1_session_id);
897         else if (priv->console_kit_cookie)
898             ck_unlock_session (priv->console_kit_cookie);
899     }
900 }
901 
902 void
session_activate(Session * session)903 session_activate (Session *session)
904 {
905     SessionPrivate *priv = session_get_instance_private (session);
906 
907     g_return_if_fail (session != NULL);
908 
909     if (getuid () == 0)
910     {
911         if (priv->login1_session_id)
912             login1_service_activate_session (login1_service_get_instance (), priv->login1_session_id);
913         else if (priv->console_kit_cookie)
914             ck_activate_session (priv->console_kit_cookie);
915     }
916 }
917 
918 void
session_stop(Session * session)919 session_stop (Session *session)
920 {
921     SessionPrivate *priv = session_get_instance_private (session);
922 
923     g_return_if_fail (session != NULL);
924 
925     if (priv->stopping)
926         return;
927     priv->stopping = TRUE;
928 
929     /* Kill remaining processes in our logind session to avoid them leaking
930      * to the user session (they share the same $DISPLAY) */
931     if (getuid () == 0 && priv->login1_session_id)
932         login1_service_terminate_session (login1_service_get_instance (), priv->login1_session_id);
933 
934     /* If can cleanly stop then do that */
935     if (session_get_is_authenticated (session) && !priv->command_run)
936     {
937         priv->command_run = TRUE;
938         write_string (session, NULL); // log filename
939         LogMode log_mode = LOG_MODE_INVALID;
940         write_data (session, &log_mode, sizeof (log_mode)); // log mode
941         write_string (session, NULL); // tty
942         write_string (session, NULL); // xauth filename
943         write_string (session, NULL); // xdisplay
944         write_xauth (session, NULL); // xauth
945         gsize n = 0;
946         write_data (session, &n, sizeof (n)); // environment
947         write_data (session, &n, sizeof (n)); // command
948         return;
949     }
950 
951     return SESSION_GET_CLASS (session)->stop (session);
952 }
953 
954 static void
session_real_stop(Session * session)955 session_real_stop (Session *session)
956 {
957     SessionPrivate *priv = session_get_instance_private (session);
958 
959     g_return_if_fail (session != NULL);
960 
961     if (priv->pid > 0)
962     {
963         l_debug (session, "Sending SIGTERM");
964         kill (priv->pid, SIGTERM);
965         // FIXME: Handle timeout
966     }
967     else
968         g_signal_emit (G_OBJECT (session), signals[STOPPED], 0);
969 }
970 
971 gboolean
session_get_is_stopping(Session * session)972 session_get_is_stopping (Session *session)
973 {
974     SessionPrivate *priv = session_get_instance_private (session);
975     g_return_val_if_fail (session != NULL, FALSE);
976     return priv->stopping;
977 }
978 
979 static void
session_init(Session * session)980 session_init (Session *session)
981 {
982     SessionPrivate *priv = session_get_instance_private (session);
983 
984     priv->log_filename = g_strdup (".xsession-errors");
985     priv->log_mode = LOG_MODE_BACKUP_AND_TRUNCATE;
986     priv->to_child_input = -1;
987     priv->from_child_output = -1;
988 }
989 
990 static void
session_finalize(GObject * object)991 session_finalize (GObject *object)
992 {
993     Session *self = SESSION (object);
994     SessionPrivate *priv = session_get_instance_private (self);
995 
996     g_clear_object (&priv->config);
997     g_clear_object (&priv->display_server);
998     if (priv->pid)
999         kill (priv->pid, SIGKILL);
1000     close (priv->to_child_input);
1001     close (priv->from_child_output);
1002     g_clear_pointer (&priv->from_child_channel, g_io_channel_unref);
1003     if (priv->from_child_watch)
1004         g_source_remove (priv->from_child_watch);
1005     if (priv->child_watch)
1006         g_source_remove (priv->child_watch);
1007     g_clear_pointer (&priv->username, g_free);
1008     g_clear_object (&priv->user);
1009     g_clear_pointer (&priv->pam_service, g_free);
1010     for (int i = 0; i < priv->messages_length; i++)
1011         g_free ((char *) priv->messages[i].msg);
1012     g_clear_pointer (&priv->messages, g_free);
1013     g_clear_pointer (&priv->authentication_result_string, g_free);
1014     g_clear_pointer (&priv->log_filename, g_free);
1015     g_clear_pointer (&priv->tty, g_free);
1016     g_clear_pointer (&priv->xdisplay, g_free);
1017     g_clear_object (&priv->x_authority);
1018     g_clear_pointer (&priv->remote_host_name, g_free);
1019     g_clear_pointer (&priv->login1_session_id, g_free);
1020     g_clear_pointer (&priv->console_kit_cookie, g_free);
1021     g_list_free_full (priv->env, g_free);
1022     g_clear_pointer (&priv->argv, g_strfreev);
1023 
1024     G_OBJECT_CLASS (session_parent_class)->finalize (object);
1025 }
1026 
1027 static void
session_class_init(SessionClass * klass)1028 session_class_init (SessionClass *klass)
1029 {
1030     GObjectClass *object_class = G_OBJECT_CLASS (klass);
1031 
1032     klass->start = session_real_start;
1033     klass->run = session_real_run;
1034     klass->stop = session_real_stop;
1035     object_class->finalize = session_finalize;
1036 
1037     signals[CREATE_GREETER] =
1038         g_signal_new (SESSION_SIGNAL_CREATE_GREETER,
1039                       G_TYPE_FROM_CLASS (klass),
1040                       G_SIGNAL_RUN_LAST,
1041                       G_STRUCT_OFFSET (SessionClass, create_greeter),
1042                       g_signal_accumulator_first_wins,
1043                       NULL,
1044                       NULL,
1045                       GREETER_TYPE, 0);
1046 
1047     signals[GOT_MESSAGES] =
1048         g_signal_new (SESSION_SIGNAL_GOT_MESSAGES,
1049                       G_TYPE_FROM_CLASS (klass),
1050                       G_SIGNAL_RUN_LAST,
1051                       G_STRUCT_OFFSET (SessionClass, got_messages),
1052                       NULL, NULL,
1053                       NULL,
1054                       G_TYPE_NONE, 0);
1055 
1056     signals[AUTHENTICATION_COMPLETE] =
1057         g_signal_new (SESSION_SIGNAL_AUTHENTICATION_COMPLETE,
1058                       G_TYPE_FROM_CLASS (klass),
1059                       G_SIGNAL_RUN_LAST,
1060                       G_STRUCT_OFFSET (SessionClass, authentication_complete),
1061                       NULL, NULL,
1062                       NULL,
1063                       G_TYPE_NONE, 0);
1064 
1065     signals[STOPPED] =
1066         g_signal_new (SESSION_SIGNAL_STOPPED,
1067                       G_TYPE_FROM_CLASS (klass),
1068                       G_SIGNAL_RUN_LAST,
1069                       G_STRUCT_OFFSET (SessionClass, stopped),
1070                       NULL, NULL,
1071                       NULL,
1072                       G_TYPE_NONE, 0);
1073 }
1074 
1075 static gint
session_real_logprefix(Logger * self,gchar * buf,gulong buflen)1076 session_real_logprefix (Logger *self, gchar *buf, gulong buflen)
1077 {
1078     Session *session = SESSION (self);
1079     SessionPrivate *priv = session_get_instance_private (session);
1080 
1081     if (priv->pid != 0)
1082         return g_snprintf (buf, buflen, "Session pid=%d: ", priv->pid);
1083     else
1084         return g_snprintf (buf, buflen, "Session: ");
1085 }
1086 
1087 static void
session_logger_iface_init(LoggerInterface * iface)1088 session_logger_iface_init (LoggerInterface *iface)
1089 {
1090     iface->logprefix = &session_real_logprefix;
1091 }
1092