1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <linux/kd.h>
6 #include <linux/vt.h>
7 #include <signal.h>
8 #include <sys/ioctl.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 
12 #include "sd-messages.h"
13 
14 #include "alloc-util.h"
15 #include "audit-util.h"
16 #include "bus-error.h"
17 #include "bus-util.h"
18 #include "devnum-util.h"
19 #include "env-file.h"
20 #include "escape.h"
21 #include "fd-util.h"
22 #include "fileio.h"
23 #include "format-util.h"
24 #include "io-util.h"
25 #include "logind-dbus.h"
26 #include "logind-seat-dbus.h"
27 #include "logind-session-dbus.h"
28 #include "logind-session.h"
29 #include "logind-user-dbus.h"
30 #include "mkdir-label.h"
31 #include "parse-util.h"
32 #include "path-util.h"
33 #include "process-util.h"
34 #include "serialize.h"
35 #include "string-table.h"
36 #include "strv.h"
37 #include "terminal-util.h"
38 #include "tmpfile-util.h"
39 #include "user-util.h"
40 #include "util.h"
41 
42 #define RELEASE_USEC (20*USEC_PER_SEC)
43 
44 static void session_remove_fifo(Session *s);
45 static void session_restore_vt(Session *s);
46 
session_new(Session ** ret,Manager * m,const char * id)47 int session_new(Session **ret, Manager *m, const char *id) {
48         _cleanup_(session_freep) Session *s = NULL;
49         int r;
50 
51         assert(ret);
52         assert(m);
53         assert(id);
54 
55         if (!session_id_valid(id))
56                 return -EINVAL;
57 
58         s = new(Session, 1);
59         if (!s)
60                 return -ENOMEM;
61 
62         *s = (Session) {
63                 .manager = m,
64                 .fifo_fd = -1,
65                 .vtfd = -1,
66                 .audit_id = AUDIT_SESSION_INVALID,
67                 .tty_validity = _TTY_VALIDITY_INVALID,
68         };
69 
70         s->state_file = path_join("/run/systemd/sessions", id);
71         if (!s->state_file)
72                 return -ENOMEM;
73 
74         s->id = basename(s->state_file);
75 
76         s->devices = hashmap_new(&devt_hash_ops);
77         if (!s->devices)
78                 return -ENOMEM;
79 
80         r = hashmap_put(m->sessions, s->id, s);
81         if (r < 0)
82                 return r;
83 
84         *ret = TAKE_PTR(s);
85         return 0;
86 }
87 
session_free(Session * s)88 Session* session_free(Session *s) {
89         SessionDevice *sd;
90 
91         if (!s)
92                 return NULL;
93 
94         if (s->in_gc_queue)
95                 LIST_REMOVE(gc_queue, s->manager->session_gc_queue, s);
96 
97         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
98 
99         session_drop_controller(s);
100 
101         while ((sd = hashmap_first(s->devices)))
102                 session_device_free(sd);
103 
104         hashmap_free(s->devices);
105 
106         if (s->user) {
107                 LIST_REMOVE(sessions_by_user, s->user->sessions, s);
108 
109                 if (s->user->display == s)
110                         s->user->display = NULL;
111 
112                 user_update_last_session_timer(s->user);
113         }
114 
115         if (s->seat) {
116                 if (s->seat->active == s)
117                         s->seat->active = NULL;
118                 if (s->seat->pending_switch == s)
119                         s->seat->pending_switch = NULL;
120 
121                 seat_evict_position(s->seat, s);
122                 LIST_REMOVE(sessions_by_seat, s->seat->sessions, s);
123         }
124 
125         if (s->scope) {
126                 hashmap_remove(s->manager->session_units, s->scope);
127                 free(s->scope);
128         }
129 
130         if (pid_is_valid(s->leader))
131                 (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
132 
133         free(s->scope_job);
134 
135         sd_bus_message_unref(s->create_message);
136 
137         free(s->tty);
138         free(s->display);
139         free(s->remote_host);
140         free(s->remote_user);
141         free(s->service);
142         free(s->desktop);
143 
144         hashmap_remove(s->manager->sessions, s->id);
145 
146         sd_event_source_unref(s->fifo_event_source);
147         safe_close(s->fifo_fd);
148 
149         /* Note that we remove neither the state file nor the fifo path here, since we want both to survive
150          * daemon restarts */
151         free(s->state_file);
152         free(s->fifo_path);
153 
154         return mfree(s);
155 }
156 
session_set_user(Session * s,User * u)157 void session_set_user(Session *s, User *u) {
158         assert(s);
159         assert(!s->user);
160 
161         s->user = u;
162         LIST_PREPEND(sessions_by_user, u->sessions, s);
163 
164         user_update_last_session_timer(u);
165 }
166 
session_set_leader(Session * s,pid_t pid)167 int session_set_leader(Session *s, pid_t pid) {
168         int r;
169 
170         assert(s);
171 
172         if (!pid_is_valid(pid))
173                 return -EINVAL;
174 
175         if (s->leader == pid)
176                 return 0;
177 
178         r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s);
179         if (r < 0)
180                 return r;
181 
182         if (pid_is_valid(s->leader))
183                 (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
184 
185         s->leader = pid;
186         (void) audit_session_from_pid(pid, &s->audit_id);
187 
188         return 1;
189 }
190 
session_save_devices(Session * s,FILE * f)191 static void session_save_devices(Session *s, FILE *f) {
192         SessionDevice *sd;
193 
194         if (!hashmap_isempty(s->devices)) {
195                 fprintf(f, "DEVICES=");
196                 HASHMAP_FOREACH(sd, s->devices)
197                         fprintf(f, "%u:%u ", major(sd->dev), minor(sd->dev));
198                 fprintf(f, "\n");
199         }
200 }
201 
session_save(Session * s)202 int session_save(Session *s) {
203         _cleanup_free_ char *temp_path = NULL;
204         _cleanup_fclose_ FILE *f = NULL;
205         int r;
206 
207         assert(s);
208 
209         if (!s->user)
210                 return -ESTALE;
211 
212         if (!s->started)
213                 return 0;
214 
215         r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
216         if (r < 0)
217                 goto fail;
218 
219         r = fopen_temporary(s->state_file, &f, &temp_path);
220         if (r < 0)
221                 goto fail;
222 
223         (void) fchmod(fileno(f), 0644);
224 
225         fprintf(f,
226                 "# This is private data. Do not parse.\n"
227                 "UID="UID_FMT"\n"
228                 "USER=%s\n"
229                 "ACTIVE=%i\n"
230                 "IS_DISPLAY=%i\n"
231                 "STATE=%s\n"
232                 "REMOTE=%i\n",
233                 s->user->user_record->uid,
234                 s->user->user_record->user_name,
235                 session_is_active(s),
236                 s->user->display == s,
237                 session_state_to_string(session_get_state(s)),
238                 s->remote);
239 
240         if (s->type >= 0)
241                 fprintf(f, "TYPE=%s\n", session_type_to_string(s->type));
242 
243         if (s->original_type >= 0)
244                 fprintf(f, "ORIGINAL_TYPE=%s\n", session_type_to_string(s->original_type));
245 
246         if (s->class >= 0)
247                 fprintf(f, "CLASS=%s\n", session_class_to_string(s->class));
248 
249         if (s->scope)
250                 fprintf(f, "SCOPE=%s\n", s->scope);
251         if (s->scope_job)
252                 fprintf(f, "SCOPE_JOB=%s\n", s->scope_job);
253 
254         if (s->fifo_path)
255                 fprintf(f, "FIFO=%s\n", s->fifo_path);
256 
257         if (s->seat)
258                 fprintf(f, "SEAT=%s\n", s->seat->id);
259 
260         if (s->tty)
261                 fprintf(f, "TTY=%s\n", s->tty);
262 
263         if (s->tty_validity >= 0)
264                 fprintf(f, "TTY_VALIDITY=%s\n", tty_validity_to_string(s->tty_validity));
265 
266         if (s->display)
267                 fprintf(f, "DISPLAY=%s\n", s->display);
268 
269         if (s->remote_host) {
270                 _cleanup_free_ char *escaped = NULL;
271 
272                 escaped = cescape(s->remote_host);
273                 if (!escaped) {
274                         r = -ENOMEM;
275                         goto fail;
276                 }
277 
278                 fprintf(f, "REMOTE_HOST=%s\n", escaped);
279         }
280 
281         if (s->remote_user) {
282                 _cleanup_free_ char *escaped = NULL;
283 
284                 escaped = cescape(s->remote_user);
285                 if (!escaped) {
286                         r = -ENOMEM;
287                         goto fail;
288                 }
289 
290                 fprintf(f, "REMOTE_USER=%s\n", escaped);
291         }
292 
293         if (s->service) {
294                 _cleanup_free_ char *escaped = NULL;
295 
296                 escaped = cescape(s->service);
297                 if (!escaped) {
298                         r = -ENOMEM;
299                         goto fail;
300                 }
301 
302                 fprintf(f, "SERVICE=%s\n", escaped);
303         }
304 
305         if (s->desktop) {
306                 _cleanup_free_ char *escaped = NULL;
307 
308                 escaped = cescape(s->desktop);
309                 if (!escaped) {
310                         r = -ENOMEM;
311                         goto fail;
312                 }
313 
314                 fprintf(f, "DESKTOP=%s\n", escaped);
315         }
316 
317         if (s->seat && seat_has_vts(s->seat))
318                 fprintf(f, "VTNR=%u\n", s->vtnr);
319 
320         if (!s->vtnr)
321                 fprintf(f, "POSITION=%u\n", s->position);
322 
323         if (pid_is_valid(s->leader))
324                 fprintf(f, "LEADER="PID_FMT"\n", s->leader);
325 
326         if (audit_session_is_valid(s->audit_id))
327                 fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
328 
329         if (dual_timestamp_is_set(&s->timestamp))
330                 fprintf(f,
331                         "REALTIME="USEC_FMT"\n"
332                         "MONOTONIC="USEC_FMT"\n",
333                         s->timestamp.realtime,
334                         s->timestamp.monotonic);
335 
336         if (s->controller) {
337                 fprintf(f, "CONTROLLER=%s\n", s->controller);
338                 session_save_devices(s, f);
339         }
340 
341         r = fflush_and_check(f);
342         if (r < 0)
343                 goto fail;
344 
345         if (rename(temp_path, s->state_file) < 0) {
346                 r = -errno;
347                 goto fail;
348         }
349 
350         return 0;
351 
352 fail:
353         (void) unlink(s->state_file);
354 
355         if (temp_path)
356                 (void) unlink(temp_path);
357 
358         return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
359 }
360 
session_load_devices(Session * s,const char * devices)361 static int session_load_devices(Session *s, const char *devices) {
362         const char *p;
363         int r = 0;
364 
365         assert(s);
366 
367         for (p = devices;;) {
368                 _cleanup_free_ char *word = NULL;
369                 SessionDevice *sd;
370                 dev_t dev;
371                 int k;
372 
373                 k = extract_first_word(&p, &word, NULL, 0);
374                 if (k == 0)
375                         break;
376                 if (k < 0) {
377                         r = k;
378                         break;
379                 }
380 
381                 k = parse_devnum(word, &dev);
382                 if (k < 0) {
383                         r = k;
384                         continue;
385                 }
386 
387                 /* The file descriptors for loaded devices will be reattached later. */
388                 k = session_device_new(s, dev, false, &sd);
389                 if (k < 0)
390                         r = k;
391         }
392 
393         if (r < 0)
394                 log_error_errno(r, "Loading session devices for session %s failed: %m", s->id);
395 
396         return r;
397 }
398 
session_load(Session * s)399 int session_load(Session *s) {
400         _cleanup_free_ char *remote = NULL,
401                 *seat = NULL,
402                 *tty_validity = NULL,
403                 *vtnr = NULL,
404                 *state = NULL,
405                 *position = NULL,
406                 *leader = NULL,
407                 *type = NULL,
408                 *original_type = NULL,
409                 *class = NULL,
410                 *uid = NULL,
411                 *realtime = NULL,
412                 *monotonic = NULL,
413                 *controller = NULL,
414                 *active = NULL,
415                 *devices = NULL,
416                 *is_display = NULL;
417 
418         int k, r;
419 
420         assert(s);
421 
422         r = parse_env_file(NULL, s->state_file,
423                            "REMOTE",         &remote,
424                            "SCOPE",          &s->scope,
425                            "SCOPE_JOB",      &s->scope_job,
426                            "FIFO",           &s->fifo_path,
427                            "SEAT",           &seat,
428                            "TTY",            &s->tty,
429                            "TTY_VALIDITY",   &tty_validity,
430                            "DISPLAY",        &s->display,
431                            "REMOTE_HOST",    &s->remote_host,
432                            "REMOTE_USER",    &s->remote_user,
433                            "SERVICE",        &s->service,
434                            "DESKTOP",        &s->desktop,
435                            "VTNR",           &vtnr,
436                            "STATE",          &state,
437                            "POSITION",       &position,
438                            "LEADER",         &leader,
439                            "TYPE",           &type,
440                            "ORIGINAL_TYPE",  &original_type,
441                            "CLASS",          &class,
442                            "UID",            &uid,
443                            "REALTIME",       &realtime,
444                            "MONOTONIC",      &monotonic,
445                            "CONTROLLER",     &controller,
446                            "ACTIVE",         &active,
447                            "DEVICES",        &devices,
448                            "IS_DISPLAY",     &is_display);
449         if (r < 0)
450                 return log_error_errno(r, "Failed to read %s: %m", s->state_file);
451 
452         if (!s->user) {
453                 uid_t u;
454                 User *user;
455 
456                 if (!uid)
457                         return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
458                                                "UID not specified for session %s",
459                                                s->id);
460 
461                 r = parse_uid(uid, &u);
462                 if (r < 0)  {
463                         log_error("Failed to parse UID value %s for session %s.", uid, s->id);
464                         return r;
465                 }
466 
467                 user = hashmap_get(s->manager->users, UID_TO_PTR(u));
468                 if (!user)
469                         return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
470                                                "User of session %s not known.",
471                                                s->id);
472 
473                 session_set_user(s, user);
474         }
475 
476         if (remote) {
477                 k = parse_boolean(remote);
478                 if (k >= 0)
479                         s->remote = k;
480         }
481 
482         if (vtnr)
483                 safe_atou(vtnr, &s->vtnr);
484 
485         if (seat && !s->seat) {
486                 Seat *o;
487 
488                 o = hashmap_get(s->manager->seats, seat);
489                 if (o)
490                         r = seat_attach_session(o, s);
491                 if (!o || r < 0)
492                         log_error("Cannot attach session %s to seat %s", s->id, seat);
493         }
494 
495         if (!s->seat || !seat_has_vts(s->seat))
496                 s->vtnr = 0;
497 
498         if (position && s->seat) {
499                 unsigned npos;
500 
501                 safe_atou(position, &npos);
502                 seat_claim_position(s->seat, s, npos);
503         }
504 
505         if (tty_validity) {
506                 TTYValidity v;
507 
508                 v = tty_validity_from_string(tty_validity);
509                 if (v < 0)
510                         log_debug("Failed to parse TTY validity: %s", tty_validity);
511                 else
512                         s->tty_validity = v;
513         }
514 
515         if (leader) {
516                 pid_t pid;
517 
518                 r = parse_pid(leader, &pid);
519                 if (r < 0)
520                         log_debug_errno(r, "Failed to parse leader PID of session: %s", leader);
521                 else {
522                         r = session_set_leader(s, pid);
523                         if (r < 0)
524                                 log_warning_errno(r, "Failed to set session leader PID, ignoring: %m");
525                 }
526         }
527 
528         if (type) {
529                 SessionType t;
530 
531                 t = session_type_from_string(type);
532                 if (t >= 0)
533                         s->type = t;
534         }
535 
536         if (original_type) {
537                 SessionType ot;
538 
539                 ot = session_type_from_string(original_type);
540                 if (ot >= 0)
541                         s->original_type = ot;
542         } else
543                 /* Pre-v246 compat: initialize original_type if not set in the state file */
544                 s->original_type = s->type;
545 
546         if (class) {
547                 SessionClass c;
548 
549                 c = session_class_from_string(class);
550                 if (c >= 0)
551                         s->class = c;
552         }
553 
554         if (state && streq(state, "closing"))
555                 s->stopping = true;
556 
557         if (s->fifo_path) {
558                 int fd;
559 
560                 /* If we open an unopened pipe for reading we will not
561                    get an EOF. to trigger an EOF we hence open it for
562                    writing, but close it right away which then will
563                    trigger the EOF. This will happen immediately if no
564                    other process has the FIFO open for writing, i. e.
565                    when the session died before logind (re)started. */
566 
567                 fd = session_create_fifo(s);
568                 safe_close(fd);
569         }
570 
571         if (realtime)
572                 (void) deserialize_usec(realtime, &s->timestamp.realtime);
573         if (monotonic)
574                 (void) deserialize_usec(monotonic, &s->timestamp.monotonic);
575 
576         if (active) {
577                 k = parse_boolean(active);
578                 if (k >= 0)
579                         s->was_active = k;
580         }
581 
582         if (is_display) {
583                 /* Note that when enumerating users are loaded before sessions, hence the display session to use is
584                  * something we have to store along with the session and not the user, as in that case we couldn't
585                  * apply it at the time we load the user. */
586 
587                 k = parse_boolean(is_display);
588                 if (k < 0)
589                         log_warning_errno(k, "Failed to parse IS_DISPLAY session property: %m");
590                 else if (k > 0)
591                         s->user->display = s;
592         }
593 
594         if (controller) {
595                 if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
596                         session_set_controller(s, controller, false, false);
597                         session_load_devices(s, devices);
598                 } else
599                         session_restore_vt(s);
600         }
601 
602         return r;
603 }
604 
session_activate(Session * s)605 int session_activate(Session *s) {
606         unsigned num_pending;
607 
608         assert(s);
609         assert(s->user);
610 
611         if (!s->seat)
612                 return -EOPNOTSUPP;
613 
614         if (s->seat->active == s)
615                 return 0;
616 
617         /* on seats with VTs, we let VTs manage session-switching */
618         if (seat_has_vts(s->seat)) {
619                 if (s->vtnr == 0)
620                         return -EOPNOTSUPP;
621 
622                 return chvt(s->vtnr);
623         }
624 
625         /* On seats without VTs, we implement session-switching in logind. We
626          * try to pause all session-devices and wait until the session
627          * controller acknowledged them. Once all devices are asleep, we simply
628          * switch the active session and be done.
629          * We save the session we want to switch to in seat->pending_switch and
630          * seat_complete_switch() will perform the final switch. */
631 
632         s->seat->pending_switch = s;
633 
634         /* if no devices are running, immediately perform the session switch */
635         num_pending = session_device_try_pause_all(s);
636         if (!num_pending)
637                 seat_complete_switch(s->seat);
638 
639         return 0;
640 }
641 
session_start_scope(Session * s,sd_bus_message * properties,sd_bus_error * error)642 static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_error *error) {
643         int r;
644 
645         assert(s);
646         assert(s->user);
647 
648         if (!s->scope) {
649                 _cleanup_free_ char *scope = NULL;
650                 const char *description;
651 
652                 s->scope_job = mfree(s->scope_job);
653 
654                 scope = strjoin("session-", s->id, ".scope");
655                 if (!scope)
656                         return log_oom();
657 
658                 description = strjoina("Session ", s->id, " of User ", s->user->user_record->user_name);
659 
660                 r = manager_start_scope(
661                                 s->manager,
662                                 scope,
663                                 s->leader,
664                                 s->user->slice,
665                                 description,
666                                 /* These two have StopWhenUnneeded= set, hence add a dep towards them */
667                                 STRV_MAKE(s->user->runtime_dir_service,
668                                           s->user->service),
669                                 /* And order us after some more */
670                                 STRV_MAKE("systemd-logind.service",
671                                           "systemd-user-sessions.service",
672                                           s->user->runtime_dir_service,
673                                           s->user->service),
674                                 user_record_home_directory(s->user->user_record),
675                                 properties,
676                                 error,
677                                 &s->scope_job);
678                 if (r < 0)
679                         return log_error_errno(r, "Failed to start session scope %s: %s",
680                                                scope, bus_error_message(error, r));
681 
682                 s->scope = TAKE_PTR(scope);
683         }
684 
685         (void) hashmap_put(s->manager->session_units, s->scope, s);
686 
687         return 0;
688 }
689 
session_start(Session * s,sd_bus_message * properties,sd_bus_error * error)690 int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
691         int r;
692 
693         assert(s);
694 
695         if (!s->user)
696                 return -ESTALE;
697 
698         if (s->stopping)
699                 return -EINVAL;
700 
701         if (s->started)
702                 return 0;
703 
704         r = user_start(s->user);
705         if (r < 0)
706                 return r;
707 
708         r = session_start_scope(s, properties, error);
709         if (r < 0)
710                 return r;
711 
712         log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
713                    "MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR,
714                    "SESSION_ID=%s", s->id,
715                    "USER_ID=%s", s->user->user_record->user_name,
716                    "LEADER="PID_FMT, s->leader,
717                    LOG_MESSAGE("New session %s of user %s.", s->id, s->user->user_record->user_name));
718 
719         if (!dual_timestamp_is_set(&s->timestamp))
720                 dual_timestamp_get(&s->timestamp);
721 
722         if (s->seat)
723                 seat_read_active_vt(s->seat);
724 
725         s->started = true;
726 
727         user_elect_display(s->user);
728 
729         /* Save data */
730         session_save(s);
731         user_save(s->user);
732         if (s->seat)
733                 seat_save(s->seat);
734 
735         /* Send signals */
736         session_send_signal(s, true);
737         user_send_changed(s->user, "Display", NULL);
738 
739         if (s->seat && s->seat->active == s)
740                 seat_send_changed(s->seat, "ActiveSession", NULL);
741 
742         return 0;
743 }
744 
session_stop_scope(Session * s,bool force)745 static int session_stop_scope(Session *s, bool force) {
746         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
747         int r;
748 
749         assert(s);
750 
751         if (!s->scope)
752                 return 0;
753 
754         /* Let's always abandon the scope first. This tells systemd that we are not interested anymore, and everything
755          * that is left in the scope is "left-over". Informing systemd about this has the benefit that it will log
756          * when killing any processes left after this point. */
757         r = manager_abandon_scope(s->manager, s->scope, &error);
758         if (r < 0) {
759                 log_warning_errno(r, "Failed to abandon session scope, ignoring: %s", bus_error_message(&error, r));
760                 sd_bus_error_free(&error);
761         }
762 
763         s->scope_job = mfree(s->scope_job);
764 
765         /* Optionally, let's kill everything that's left now. */
766         if (force ||
767             (s->user->user_record->kill_processes != 0 &&
768              (s->user->user_record->kill_processes > 0 ||
769               manager_shall_kill(s->manager, s->user->user_record->user_name)))) {
770 
771                 r = manager_stop_unit(s->manager, s->scope, force ? "replace" : "fail", &error, &s->scope_job);
772                 if (r < 0) {
773                         if (force)
774                                 return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r));
775 
776                         log_warning_errno(r, "Failed to stop session scope, ignoring: %s", bus_error_message(&error, r));
777                 }
778         } else {
779 
780                 /* With no killing, this session is allowed to persist in "closing" state indefinitely.
781                  * Therefore session stop and session removal may be two distinct events.
782                  * Session stop is quite significant on its own, let's log it. */
783                 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
784                            "SESSION_ID=%s", s->id,
785                            "USER_ID=%s", s->user->user_record->user_name,
786                            "LEADER="PID_FMT, s->leader,
787                            LOG_MESSAGE("Session %s logged out. Waiting for processes to exit.", s->id));
788         }
789 
790         return 0;
791 }
792 
session_stop(Session * s,bool force)793 int session_stop(Session *s, bool force) {
794         int r;
795 
796         assert(s);
797 
798         /* This is called whenever we begin with tearing down a session record. It's called in four cases: explicit API
799          * request via the bus (either directly for the session object or for the seat or user object this session
800          * belongs to; 'force' is true), or due to automatic GC (i.e. scope vanished; 'force' is false), or because the
801          * session FIFO saw an EOF ('force' is false), or because the release timer hit ('force' is false). */
802 
803         if (!s->user)
804                 return -ESTALE;
805         if (!s->started)
806                 return 0;
807         if (s->stopping)
808                 return 0;
809 
810         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
811 
812         if (s->seat)
813                 seat_evict_position(s->seat, s);
814 
815         /* We are going down, don't care about FIFOs anymore */
816         session_remove_fifo(s);
817 
818         /* Kill cgroup */
819         r = session_stop_scope(s, force);
820 
821         s->stopping = true;
822 
823         user_elect_display(s->user);
824 
825         session_save(s);
826         user_save(s->user);
827 
828         return r;
829 }
830 
session_finalize(Session * s)831 int session_finalize(Session *s) {
832         SessionDevice *sd;
833 
834         assert(s);
835 
836         if (!s->user)
837                 return -ESTALE;
838 
839         if (s->started)
840                 log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
841                            "MESSAGE_ID=" SD_MESSAGE_SESSION_STOP_STR,
842                            "SESSION_ID=%s", s->id,
843                            "USER_ID=%s", s->user->user_record->user_name,
844                            "LEADER="PID_FMT, s->leader,
845                            LOG_MESSAGE("Removed session %s.", s->id));
846 
847         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
848 
849         if (s->seat)
850                 seat_evict_position(s->seat, s);
851 
852         /* Kill session devices */
853         while ((sd = hashmap_first(s->devices)))
854                 session_device_free(sd);
855 
856         (void) unlink(s->state_file);
857         session_add_to_gc_queue(s);
858         user_add_to_gc_queue(s->user);
859 
860         if (s->started) {
861                 session_send_signal(s, false);
862                 s->started = false;
863         }
864 
865         if (s->seat) {
866                 if (s->seat->active == s)
867                         seat_set_active(s->seat, NULL);
868 
869                 seat_save(s->seat);
870         }
871 
872         user_save(s->user);
873         user_send_changed(s->user, "Display", NULL);
874 
875         return 0;
876 }
877 
release_timeout_callback(sd_event_source * es,uint64_t usec,void * userdata)878 static int release_timeout_callback(sd_event_source *es, uint64_t usec, void *userdata) {
879         Session *s = userdata;
880 
881         assert(es);
882         assert(s);
883 
884         session_stop(s, /* force = */ false);
885         return 0;
886 }
887 
session_release(Session * s)888 int session_release(Session *s) {
889         assert(s);
890 
891         if (!s->started || s->stopping)
892                 return 0;
893 
894         if (s->timer_event_source)
895                 return 0;
896 
897         return sd_event_add_time_relative(
898                         s->manager->event,
899                         &s->timer_event_source,
900                         CLOCK_MONOTONIC,
901                         RELEASE_USEC, 0,
902                         release_timeout_callback, s);
903 }
904 
session_is_active(Session * s)905 bool session_is_active(Session *s) {
906         assert(s);
907 
908         if (!s->seat)
909                 return true;
910 
911         return s->seat->active == s;
912 }
913 
get_tty_atime(const char * tty,usec_t * atime)914 static int get_tty_atime(const char *tty, usec_t *atime) {
915         _cleanup_free_ char *p = NULL;
916         struct stat st;
917 
918         assert(tty);
919         assert(atime);
920 
921         if (!path_is_absolute(tty)) {
922                 p = path_join("/dev", tty);
923                 if (!p)
924                         return -ENOMEM;
925 
926                 tty = p;
927         } else if (!path_startswith(tty, "/dev/"))
928                 return -ENOENT;
929 
930         if (lstat(tty, &st) < 0)
931                 return -errno;
932 
933         *atime = timespec_load(&st.st_atim);
934         return 0;
935 }
936 
get_process_ctty_atime(pid_t pid,usec_t * atime)937 static int get_process_ctty_atime(pid_t pid, usec_t *atime) {
938         _cleanup_free_ char *p = NULL;
939         int r;
940 
941         assert(pid > 0);
942         assert(atime);
943 
944         r = get_ctty(pid, NULL, &p);
945         if (r < 0)
946                 return r;
947 
948         return get_tty_atime(p, atime);
949 }
950 
session_get_idle_hint(Session * s,dual_timestamp * t)951 int session_get_idle_hint(Session *s, dual_timestamp *t) {
952         usec_t atime = 0;
953         int r;
954 
955         assert(s);
956 
957         /* Graphical sessions have an explicit idle hint */
958         if (SESSION_TYPE_IS_GRAPHICAL(s->type)) {
959                 if (t)
960                         *t = s->idle_hint_timestamp;
961 
962                 return s->idle_hint;
963         }
964 
965         /* For sessions with an explicitly configured tty, let's check its atime */
966         if (s->tty) {
967                 r = get_tty_atime(s->tty, &atime);
968                 if (r >= 0)
969                         goto found_atime;
970         }
971 
972         /* For sessions with a leader but no explicitly configured tty, let's check the controlling tty of
973          * the leader */
974         if (pid_is_valid(s->leader)) {
975                 r = get_process_ctty_atime(s->leader, &atime);
976                 if (r >= 0)
977                         goto found_atime;
978         }
979 
980         if (t)
981                 *t = DUAL_TIMESTAMP_NULL;
982 
983         return false;
984 
985 found_atime:
986         if (t)
987                 dual_timestamp_from_realtime(t, atime);
988 
989         if (s->manager->idle_action_usec <= 0)
990                 return false;
991 
992         return usec_add(atime, s->manager->idle_action_usec) <= now(CLOCK_REALTIME);
993 }
994 
session_set_idle_hint(Session * s,bool b)995 int session_set_idle_hint(Session *s, bool b) {
996         assert(s);
997 
998         if (!SESSION_TYPE_IS_GRAPHICAL(s->type))
999                 return -ENOTTY;
1000 
1001         if (s->idle_hint == b)
1002                 return 0;
1003 
1004         s->idle_hint = b;
1005         dual_timestamp_get(&s->idle_hint_timestamp);
1006 
1007         session_send_changed(s, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1008 
1009         if (s->seat)
1010                 seat_send_changed(s->seat, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1011 
1012         user_send_changed(s->user, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1013         manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
1014 
1015         return 1;
1016 }
1017 
session_get_locked_hint(Session * s)1018 int session_get_locked_hint(Session *s) {
1019         assert(s);
1020 
1021         return s->locked_hint;
1022 }
1023 
session_set_locked_hint(Session * s,bool b)1024 void session_set_locked_hint(Session *s, bool b) {
1025         assert(s);
1026 
1027         if (s->locked_hint == b)
1028                 return;
1029 
1030         s->locked_hint = b;
1031 
1032         session_send_changed(s, "LockedHint", NULL);
1033 }
1034 
session_set_type(Session * s,SessionType t)1035 void session_set_type(Session *s, SessionType t) {
1036         assert(s);
1037 
1038         if (s->type == t)
1039                 return;
1040 
1041         s->type = t;
1042         session_save(s);
1043 
1044         session_send_changed(s, "Type", NULL);
1045 }
1046 
session_dispatch_fifo(sd_event_source * es,int fd,uint32_t revents,void * userdata)1047 static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
1048         Session *s = userdata;
1049 
1050         assert(s);
1051         assert(s->fifo_fd == fd);
1052 
1053         /* EOF on the FIFO means the session died abnormally. */
1054 
1055         session_remove_fifo(s);
1056         session_stop(s, /* force = */ false);
1057 
1058         return 1;
1059 }
1060 
session_create_fifo(Session * s)1061 int session_create_fifo(Session *s) {
1062         int r;
1063 
1064         assert(s);
1065 
1066         /* Create FIFO */
1067         if (!s->fifo_path) {
1068                 r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
1069                 if (r < 0)
1070                         return r;
1071 
1072                 s->fifo_path = strjoin("/run/systemd/sessions/", s->id, ".ref");
1073                 if (!s->fifo_path)
1074                         return -ENOMEM;
1075 
1076                 if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST)
1077                         return -errno;
1078         }
1079 
1080         /* Open reading side */
1081         if (s->fifo_fd < 0) {
1082                 s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
1083                 if (s->fifo_fd < 0)
1084                         return -errno;
1085         }
1086 
1087         if (!s->fifo_event_source) {
1088                 r = sd_event_add_io(s->manager->event, &s->fifo_event_source, s->fifo_fd, 0, session_dispatch_fifo, s);
1089                 if (r < 0)
1090                         return r;
1091 
1092                 /* Let's make sure we noticed dead sessions before we process new bus requests (which might
1093                  * create new sessions). */
1094                 r = sd_event_source_set_priority(s->fifo_event_source, SD_EVENT_PRIORITY_NORMAL-10);
1095                 if (r < 0)
1096                         return r;
1097         }
1098 
1099         /* Open writing side */
1100         return RET_NERRNO(open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NONBLOCK));
1101 }
1102 
session_remove_fifo(Session * s)1103 static void session_remove_fifo(Session *s) {
1104         assert(s);
1105 
1106         s->fifo_event_source = sd_event_source_unref(s->fifo_event_source);
1107         s->fifo_fd = safe_close(s->fifo_fd);
1108 
1109         if (s->fifo_path) {
1110                 (void) unlink(s->fifo_path);
1111                 s->fifo_path = mfree(s->fifo_path);
1112         }
1113 }
1114 
session_may_gc(Session * s,bool drop_not_started)1115 bool session_may_gc(Session *s, bool drop_not_started) {
1116         int r;
1117 
1118         assert(s);
1119 
1120         if (drop_not_started && !s->started)
1121                 return true;
1122 
1123         if (!s->user)
1124                 return true;
1125 
1126         if (s->fifo_fd >= 0) {
1127                 if (pipe_eof(s->fifo_fd) <= 0)
1128                         return false;
1129         }
1130 
1131         if (s->scope_job) {
1132                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1133 
1134                 r = manager_job_is_active(s->manager, s->scope_job, &error);
1135                 if (r < 0)
1136                         log_debug_errno(r, "Failed to determine whether job '%s' is pending, ignoring: %s", s->scope_job, bus_error_message(&error, r));
1137                 if (r != 0)
1138                         return false;
1139         }
1140 
1141         if (s->scope) {
1142                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1143 
1144                 r = manager_unit_is_active(s->manager, s->scope, &error);
1145                 if (r < 0)
1146                         log_debug_errno(r, "Failed to determine whether unit '%s' is active, ignoring: %s", s->scope, bus_error_message(&error, r));
1147                 if (r != 0)
1148                         return false;
1149         }
1150 
1151         return true;
1152 }
1153 
session_add_to_gc_queue(Session * s)1154 void session_add_to_gc_queue(Session *s) {
1155         assert(s);
1156 
1157         if (s->in_gc_queue)
1158                 return;
1159 
1160         LIST_PREPEND(gc_queue, s->manager->session_gc_queue, s);
1161         s->in_gc_queue = true;
1162 }
1163 
session_get_state(Session * s)1164 SessionState session_get_state(Session *s) {
1165         assert(s);
1166 
1167         /* always check closing first */
1168         if (s->stopping || s->timer_event_source)
1169                 return SESSION_CLOSING;
1170 
1171         if (s->scope_job || s->fifo_fd < 0)
1172                 return SESSION_OPENING;
1173 
1174         if (session_is_active(s))
1175                 return SESSION_ACTIVE;
1176 
1177         return SESSION_ONLINE;
1178 }
1179 
session_kill(Session * s,KillWho who,int signo)1180 int session_kill(Session *s, KillWho who, int signo) {
1181         assert(s);
1182 
1183         if (!s->scope)
1184                 return -ESRCH;
1185 
1186         return manager_kill_unit(s->manager, s->scope, who, signo, NULL);
1187 }
1188 
session_open_vt(Session * s)1189 static int session_open_vt(Session *s) {
1190         char path[sizeof("/dev/tty") + DECIMAL_STR_MAX(s->vtnr)];
1191 
1192         if (s->vtnr < 1)
1193                 return -ENODEV;
1194 
1195         if (s->vtfd >= 0)
1196                 return s->vtfd;
1197 
1198         sprintf(path, "/dev/tty%u", s->vtnr);
1199         s->vtfd = open_terminal(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
1200         if (s->vtfd < 0)
1201                 return log_error_errno(s->vtfd, "cannot open VT %s of session %s: %m", path, s->id);
1202 
1203         return s->vtfd;
1204 }
1205 
session_prepare_vt(Session * s)1206 static int session_prepare_vt(Session *s) {
1207         int vt, r;
1208         struct vt_mode mode = {};
1209 
1210         if (s->vtnr < 1)
1211                 return 0;
1212 
1213         vt = session_open_vt(s);
1214         if (vt < 0)
1215                 return vt;
1216 
1217         r = fchown(vt, s->user->user_record->uid, -1);
1218         if (r < 0) {
1219                 r = log_error_errno(errno,
1220                                     "Cannot change owner of /dev/tty%u: %m",
1221                                     s->vtnr);
1222                 goto error;
1223         }
1224 
1225         r = ioctl(vt, KDSKBMODE, K_OFF);
1226         if (r < 0) {
1227                 r = log_error_errno(errno,
1228                                     "Cannot set K_OFF on /dev/tty%u: %m",
1229                                     s->vtnr);
1230                 goto error;
1231         }
1232 
1233         r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
1234         if (r < 0) {
1235                 r = log_error_errno(errno,
1236                                     "Cannot set KD_GRAPHICS on /dev/tty%u: %m",
1237                                     s->vtnr);
1238                 goto error;
1239         }
1240 
1241         /* Oh, thanks to the VT layer, VT_AUTO does not work with KD_GRAPHICS.
1242          * So we need a dummy handler here which just acknowledges *all* VT
1243          * switch requests. */
1244         mode.mode = VT_PROCESS;
1245         mode.relsig = SIGRTMIN;
1246         mode.acqsig = SIGRTMIN + 1;
1247         r = ioctl(vt, VT_SETMODE, &mode);
1248         if (r < 0) {
1249                 r = log_error_errno(errno,
1250                                     "Cannot set VT_PROCESS on /dev/tty%u: %m",
1251                                     s->vtnr);
1252                 goto error;
1253         }
1254 
1255         return 0;
1256 
1257 error:
1258         session_restore_vt(s);
1259         return r;
1260 }
1261 
session_restore_vt(Session * s)1262 static void session_restore_vt(Session *s) {
1263         int r;
1264 
1265         r = vt_restore(s->vtfd);
1266         if (r == -EIO) {
1267                 int vt, old_fd;
1268 
1269                 /* It might happen if the controlling process exited before or while we were
1270                  * restoring the VT as it would leave the old file-descriptor in a hung-up
1271                  * state. In this case let's retry with a fresh handle to the virtual terminal. */
1272 
1273                 /* We do a little dance to avoid having the terminal be available
1274                  * for reuse before we've cleaned it up. */
1275                 old_fd = TAKE_FD(s->vtfd);
1276 
1277                 vt = session_open_vt(s);
1278                 safe_close(old_fd);
1279 
1280                 if (vt >= 0)
1281                         r = vt_restore(vt);
1282         }
1283 
1284         if (r < 0)
1285                 log_warning_errno(r, "Failed to restore VT, ignoring: %m");
1286 
1287         s->vtfd = safe_close(s->vtfd);
1288 }
1289 
session_leave_vt(Session * s)1290 void session_leave_vt(Session *s) {
1291         int r;
1292 
1293         assert(s);
1294 
1295         /* This is called whenever we get a VT-switch signal from the kernel.
1296          * We acknowledge all of them unconditionally. Note that session are
1297          * free to overwrite those handlers and we only register them for
1298          * sessions with controllers. Legacy sessions are not affected.
1299          * However, if we switch from a non-legacy to a legacy session, we must
1300          * make sure to pause all device before acknowledging the switch. We
1301          * process the real switch only after we are notified via sysfs, so the
1302          * legacy session might have already started using the devices. If we
1303          * don't pause the devices before the switch, we might confuse the
1304          * session we switch to. */
1305 
1306         if (s->vtfd < 0)
1307                 return;
1308 
1309         session_device_pause_all(s);
1310         r = vt_release(s->vtfd, false);
1311         if (r < 0)
1312                 log_debug_errno(r, "Cannot release VT of session %s: %m", s->id);
1313 }
1314 
session_is_controller(Session * s,const char * sender)1315 bool session_is_controller(Session *s, const char *sender) {
1316         assert(s);
1317 
1318         return streq_ptr(s->controller, sender);
1319 }
1320 
session_release_controller(Session * s,bool notify)1321 static void session_release_controller(Session *s, bool notify) {
1322         _unused_ _cleanup_free_ char *name = NULL;
1323         SessionDevice *sd;
1324 
1325         if (!s->controller)
1326                 return;
1327 
1328         name = s->controller;
1329 
1330         /* By resetting the controller before releasing the devices, we won't send notification signals.
1331          * This avoids sending useless notifications if the controller is released on disconnects. */
1332         if (!notify)
1333                 s->controller = NULL;
1334 
1335         while ((sd = hashmap_first(s->devices)))
1336                 session_device_free(sd);
1337 
1338         s->controller = NULL;
1339         s->track = sd_bus_track_unref(s->track);
1340 }
1341 
on_bus_track(sd_bus_track * track,void * userdata)1342 static int on_bus_track(sd_bus_track *track, void *userdata) {
1343         Session *s = userdata;
1344 
1345         assert(track);
1346         assert(s);
1347 
1348         session_drop_controller(s);
1349 
1350         return 0;
1351 }
1352 
session_set_controller(Session * s,const char * sender,bool force,bool prepare)1353 int session_set_controller(Session *s, const char *sender, bool force, bool prepare) {
1354         _cleanup_free_ char *name = NULL;
1355         int r;
1356 
1357         assert(s);
1358         assert(sender);
1359 
1360         if (session_is_controller(s, sender))
1361                 return 0;
1362         if (s->controller && !force)
1363                 return -EBUSY;
1364 
1365         name = strdup(sender);
1366         if (!name)
1367                 return -ENOMEM;
1368 
1369         s->track = sd_bus_track_unref(s->track);
1370         r = sd_bus_track_new(s->manager->bus, &s->track, on_bus_track, s);
1371         if (r < 0)
1372                 return r;
1373 
1374         r = sd_bus_track_add_name(s->track, name);
1375         if (r < 0)
1376                 return r;
1377 
1378         /* When setting a session controller, we forcibly mute the VT and set
1379          * it into graphics-mode. Applications can override that by changing
1380          * VT state after calling TakeControl(). However, this serves as a good
1381          * default and well-behaving controllers can now ignore VTs entirely.
1382          * Note that we reset the VT on ReleaseControl() and if the controller
1383          * exits.
1384          * If logind crashes/restarts, we restore the controller during restart
1385          * (without preparing the VT since the controller has probably overridden
1386          * VT state by now) or reset the VT in case it crashed/exited, too. */
1387         if (prepare) {
1388                 r = session_prepare_vt(s);
1389                 if (r < 0) {
1390                         s->track = sd_bus_track_unref(s->track);
1391                         return r;
1392                 }
1393         }
1394 
1395         session_release_controller(s, true);
1396         s->controller = TAKE_PTR(name);
1397         session_save(s);
1398 
1399         return 0;
1400 }
1401 
session_drop_controller(Session * s)1402 void session_drop_controller(Session *s) {
1403         assert(s);
1404 
1405         if (!s->controller)
1406                 return;
1407 
1408         s->track = sd_bus_track_unref(s->track);
1409         session_set_type(s, s->original_type);
1410         session_release_controller(s, false);
1411         session_save(s);
1412         session_restore_vt(s);
1413 }
1414 
1415 static const char* const session_state_table[_SESSION_STATE_MAX] = {
1416         [SESSION_OPENING] = "opening",
1417         [SESSION_ONLINE]  = "online",
1418         [SESSION_ACTIVE]  = "active",
1419         [SESSION_CLOSING] = "closing",
1420 };
1421 
1422 DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
1423 
1424 static const char* const session_type_table[_SESSION_TYPE_MAX] = {
1425         [SESSION_UNSPECIFIED] = "unspecified",
1426         [SESSION_TTY]         = "tty",
1427         [SESSION_X11]         = "x11",
1428         [SESSION_WAYLAND]     = "wayland",
1429         [SESSION_MIR]         = "mir",
1430         [SESSION_WEB]         = "web",
1431 };
1432 
1433 DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
1434 
1435 static const char* const session_class_table[_SESSION_CLASS_MAX] = {
1436         [SESSION_USER]        = "user",
1437         [SESSION_GREETER]     = "greeter",
1438         [SESSION_LOCK_SCREEN] = "lock-screen",
1439         [SESSION_BACKGROUND]  = "background",
1440 };
1441 
1442 DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
1443 
1444 static const char* const kill_who_table[_KILL_WHO_MAX] = {
1445         [KILL_LEADER] = "leader",
1446         [KILL_ALL]    = "all",
1447 };
1448 
1449 DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);
1450 
1451 static const char* const tty_validity_table[_TTY_VALIDITY_MAX] = {
1452         [TTY_FROM_PAM]          = "from-pam",
1453         [TTY_FROM_UTMP]         = "from-utmp",
1454         [TTY_UTMP_INCONSISTENT] = "utmp-inconsistent",
1455 };
1456 
1457 DEFINE_STRING_TABLE_LOOKUP(tty_validity, TTYValidity);
1458