chiark / gitweb /
logind: restore logic to kill user processes when session ends
[elogind.git] / src / login / logind.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <pwd.h>
24 #include <libudev.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/epoll.h>
29 #include <sys/ioctl.h>
30 #include <linux/vt.h>
31 #include <sys/timerfd.h>
32
33 #include <systemd/sd-daemon.h>
34
35 #include "logind.h"
36 #include "dbus-common.h"
37 #include "dbus-loop.h"
38 #include "strv.h"
39 #include "conf-parser.h"
40 #include "mkdir.h"
41
42 Manager *manager_new(void) {
43         Manager *m;
44
45         m = new0(Manager, 1);
46         if (!m)
47                 return NULL;
48
49         m->console_active_fd = -1;
50         m->bus_fd = -1;
51         m->udev_seat_fd = -1;
52         m->udev_vcsa_fd = -1;
53         m->udev_button_fd = -1;
54         m->epoll_fd = -1;
55         m->reserve_vt_fd = -1;
56
57         m->n_autovts = 6;
58         m->reserve_vt = 6;
59         m->inhibit_delay_max = 5 * USEC_PER_SEC;
60         m->handle_power_key = HANDLE_POWEROFF;
61         m->handle_suspend_key = HANDLE_SUSPEND;
62         m->handle_hibernate_key = HANDLE_HIBERNATE;
63         m->handle_lid_switch = HANDLE_SUSPEND;
64         m->lid_switch_ignore_inhibited = true;
65
66         m->idle_action_fd = -1;
67         m->idle_action_usec = 30 * USEC_PER_MINUTE;
68         m->idle_action = HANDLE_IGNORE;
69         m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
70
71         m->devices = hashmap_new(string_hash_func, string_compare_func);
72         m->seats = hashmap_new(string_hash_func, string_compare_func);
73         m->sessions = hashmap_new(string_hash_func, string_compare_func);
74         m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
75         m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
76         m->buttons = hashmap_new(string_hash_func, string_compare_func);
77
78         m->user_units = hashmap_new(string_hash_func, string_compare_func);
79         m->session_units = hashmap_new(string_hash_func, string_compare_func);
80
81         m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
82         m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
83         m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
84
85         if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
86             !m->user_units || !m->session_units ||
87             !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
88                 manager_free(m);
89                 return NULL;
90         }
91
92         m->kill_exclude_users = strv_new("root", NULL);
93         if (!m->kill_exclude_users) {
94                 manager_free(m);
95                 return NULL;
96         }
97
98         m->udev = udev_new();
99         if (!m->udev) {
100                 manager_free(m);
101                 return NULL;
102         }
103
104         return m;
105 }
106
107 void manager_free(Manager *m) {
108         Session *session;
109         User *u;
110         Device *d;
111         Seat *s;
112         Inhibitor *i;
113         Button *b;
114
115         assert(m);
116
117         while ((session = hashmap_first(m->sessions)))
118                 session_free(session);
119
120         while ((u = hashmap_first(m->users)))
121                 user_free(u);
122
123         while ((d = hashmap_first(m->devices)))
124                 device_free(d);
125
126         while ((s = hashmap_first(m->seats)))
127                 seat_free(s);
128
129         while ((i = hashmap_first(m->inhibitors)))
130                 inhibitor_free(i);
131
132         while ((b = hashmap_first(m->buttons)))
133                 button_free(b);
134
135         hashmap_free(m->devices);
136         hashmap_free(m->seats);
137         hashmap_free(m->sessions);
138         hashmap_free(m->users);
139         hashmap_free(m->inhibitors);
140         hashmap_free(m->buttons);
141
142         hashmap_free(m->user_units);
143         hashmap_free(m->session_units);
144
145         hashmap_free(m->session_fds);
146         hashmap_free(m->inhibitor_fds);
147         hashmap_free(m->button_fds);
148
149         if (m->console_active_fd >= 0)
150                 close_nointr_nofail(m->console_active_fd);
151
152         if (m->udev_seat_monitor)
153                 udev_monitor_unref(m->udev_seat_monitor);
154         if (m->udev_vcsa_monitor)
155                 udev_monitor_unref(m->udev_vcsa_monitor);
156         if (m->udev_button_monitor)
157                 udev_monitor_unref(m->udev_button_monitor);
158
159         if (m->udev)
160                 udev_unref(m->udev);
161
162         if (m->bus) {
163                 dbus_connection_flush(m->bus);
164                 dbus_connection_close(m->bus);
165                 dbus_connection_unref(m->bus);
166         }
167
168         if (m->bus_fd >= 0)
169                 close_nointr_nofail(m->bus_fd);
170
171         if (m->epoll_fd >= 0)
172                 close_nointr_nofail(m->epoll_fd);
173
174         if (m->reserve_vt_fd >= 0)
175                 close_nointr_nofail(m->reserve_vt_fd);
176
177         if (m->idle_action_fd >= 0)
178                 close_nointr_nofail(m->idle_action_fd);
179
180         strv_free(m->kill_only_users);
181         strv_free(m->kill_exclude_users);
182
183         free(m->action_job);
184         free(m);
185 }
186
187 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
188         Device *d;
189
190         assert(m);
191         assert(sysfs);
192
193         d = hashmap_get(m->devices, sysfs);
194         if (d) {
195                 if (_device)
196                         *_device = d;
197
198                 return 0;
199         }
200
201         d = device_new(m, sysfs);
202         if (!d)
203                 return -ENOMEM;
204
205         if (_device)
206                 *_device = d;
207
208         return 0;
209 }
210
211 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
212         Seat *s;
213
214         assert(m);
215         assert(id);
216
217         s = hashmap_get(m->seats, id);
218         if (s) {
219                 if (_seat)
220                         *_seat = s;
221
222                 return 0;
223         }
224
225         s = seat_new(m, id);
226         if (!s)
227                 return -ENOMEM;
228
229         if (_seat)
230                 *_seat = s;
231
232         return 0;
233 }
234
235 int manager_add_session(Manager *m, const char *id, Session **_session) {
236         Session *s;
237
238         assert(m);
239         assert(id);
240
241         s = hashmap_get(m->sessions, id);
242         if (s) {
243                 if (_session)
244                         *_session = s;
245
246                 return 0;
247         }
248
249         s = session_new(m, id);
250         if (!s)
251                 return -ENOMEM;
252
253         if (_session)
254                 *_session = s;
255
256         return 0;
257 }
258
259 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
260         User *u;
261
262         assert(m);
263         assert(name);
264
265         u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
266         if (u) {
267                 if (_user)
268                         *_user = u;
269
270                 return 0;
271         }
272
273         u = user_new(m, uid, gid, name);
274         if (!u)
275                 return -ENOMEM;
276
277         if (_user)
278                 *_user = u;
279
280         return 0;
281 }
282
283 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
284         uid_t uid;
285         gid_t gid;
286         int r;
287
288         assert(m);
289         assert(name);
290
291         r = get_user_creds(&name, &uid, &gid, NULL, NULL);
292         if (r < 0)
293                 return r;
294
295         return manager_add_user(m, uid, gid, name, _user);
296 }
297
298 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
299         struct passwd *p;
300
301         assert(m);
302
303         errno = 0;
304         p = getpwuid(uid);
305         if (!p)
306                 return errno ? -errno : -ENOENT;
307
308         return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
309 }
310
311 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
312         Inhibitor *i;
313
314         assert(m);
315         assert(id);
316
317         i = hashmap_get(m->inhibitors, id);
318         if (i) {
319                 if (_inhibitor)
320                         *_inhibitor = i;
321
322                 return 0;
323         }
324
325         i = inhibitor_new(m, id);
326         if (!i)
327                 return -ENOMEM;
328
329         if (_inhibitor)
330                 *_inhibitor = i;
331
332         return 0;
333 }
334
335 int manager_add_button(Manager *m, const char *name, Button **_button) {
336         Button *b;
337
338         assert(m);
339         assert(name);
340
341         b = hashmap_get(m->buttons, name);
342         if (b) {
343                 if (_button)
344                         *_button = b;
345
346                 return 0;
347         }
348
349         b = button_new(m, name);
350         if (!b)
351                 return -ENOMEM;
352
353         if (_button)
354                 *_button = b;
355
356         return 0;
357 }
358
359 int manager_process_seat_device(Manager *m, struct udev_device *d) {
360         Device *device;
361         int r;
362
363         assert(m);
364
365         if (streq_ptr(udev_device_get_action(d), "remove")) {
366
367                 device = hashmap_get(m->devices, udev_device_get_syspath(d));
368                 if (!device)
369                         return 0;
370
371                 seat_add_to_gc_queue(device->seat);
372                 device_free(device);
373
374         } else {
375                 const char *sn;
376                 Seat *seat;
377
378                 sn = udev_device_get_property_value(d, "ID_SEAT");
379                 if (isempty(sn))
380                         sn = "seat0";
381
382                 if (!seat_name_is_valid(sn)) {
383                         log_warning("Device with invalid seat name %s found, ignoring.", sn);
384                         return 0;
385                 }
386
387                 r = manager_add_device(m, udev_device_get_syspath(d), &device);
388                 if (r < 0)
389                         return r;
390
391                 r = manager_add_seat(m, sn, &seat);
392                 if (r < 0) {
393                         if (!device->seat)
394                                 device_free(device);
395
396                         return r;
397                 }
398
399                 device_attach(device, seat);
400                 seat_start(seat);
401         }
402
403         return 0;
404 }
405
406 int manager_process_button_device(Manager *m, struct udev_device *d) {
407         Button *b;
408
409         int r;
410
411         assert(m);
412
413         if (streq_ptr(udev_device_get_action(d), "remove")) {
414
415                 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
416                 if (!b)
417                         return 0;
418
419                 button_free(b);
420
421         } else {
422                 const char *sn;
423
424                 r = manager_add_button(m, udev_device_get_sysname(d), &b);
425                 if (r < 0)
426                         return r;
427
428                 sn = udev_device_get_property_value(d, "ID_SEAT");
429                 if (isempty(sn))
430                         sn = "seat0";
431
432                 button_set_seat(b, sn);
433                 button_open(b);
434         }
435
436         return 0;
437 }
438
439 int manager_enumerate_devices(Manager *m) {
440         struct udev_list_entry *item = NULL, *first = NULL;
441         struct udev_enumerate *e;
442         int r;
443
444         assert(m);
445
446         /* Loads devices from udev and creates seats for them as
447          * necessary */
448
449         e = udev_enumerate_new(m->udev);
450         if (!e) {
451                 r = -ENOMEM;
452                 goto finish;
453         }
454
455         r = udev_enumerate_add_match_tag(e, "master-of-seat");
456         if (r < 0)
457                 goto finish;
458
459         r = udev_enumerate_scan_devices(e);
460         if (r < 0)
461                 goto finish;
462
463         first = udev_enumerate_get_list_entry(e);
464         udev_list_entry_foreach(item, first) {
465                 struct udev_device *d;
466                 int k;
467
468                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
469                 if (!d) {
470                         r = -ENOMEM;
471                         goto finish;
472                 }
473
474                 k = manager_process_seat_device(m, d);
475                 udev_device_unref(d);
476
477                 if (k < 0)
478                         r = k;
479         }
480
481 finish:
482         if (e)
483                 udev_enumerate_unref(e);
484
485         return r;
486 }
487
488 int manager_enumerate_buttons(Manager *m) {
489         struct udev_list_entry *item = NULL, *first = NULL;
490         struct udev_enumerate *e;
491         int r;
492
493         assert(m);
494
495         /* Loads buttons from udev */
496
497         if (m->handle_power_key == HANDLE_IGNORE &&
498             m->handle_suspend_key == HANDLE_IGNORE &&
499             m->handle_hibernate_key == HANDLE_IGNORE &&
500             m->handle_lid_switch == HANDLE_IGNORE)
501                 return 0;
502
503         e = udev_enumerate_new(m->udev);
504         if (!e) {
505                 r = -ENOMEM;
506                 goto finish;
507         }
508
509         r = udev_enumerate_add_match_subsystem(e, "input");
510         if (r < 0)
511                 goto finish;
512
513         r = udev_enumerate_add_match_tag(e, "power-switch");
514         if (r < 0)
515                 goto finish;
516
517         r = udev_enumerate_scan_devices(e);
518         if (r < 0)
519                 goto finish;
520
521         first = udev_enumerate_get_list_entry(e);
522         udev_list_entry_foreach(item, first) {
523                 struct udev_device *d;
524                 int k;
525
526                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
527                 if (!d) {
528                         r = -ENOMEM;
529                         goto finish;
530                 }
531
532                 k = manager_process_button_device(m, d);
533                 udev_device_unref(d);
534
535                 if (k < 0)
536                         r = k;
537         }
538
539 finish:
540         if (e)
541                 udev_enumerate_unref(e);
542
543         return r;
544 }
545
546 int manager_enumerate_seats(Manager *m) {
547         _cleanup_closedir_ DIR *d = NULL;
548         struct dirent *de;
549         int r = 0;
550
551         assert(m);
552
553         /* This loads data about seats stored on disk, but does not
554          * actually create any seats. Removes data of seats that no
555          * longer exist. */
556
557         d = opendir("/run/systemd/seats");
558         if (!d) {
559                 if (errno == ENOENT)
560                         return 0;
561
562                 log_error("Failed to open /run/systemd/seats: %m");
563                 return -errno;
564         }
565
566         FOREACH_DIRENT(de, d, return -errno) {
567                 Seat *s;
568                 int k;
569
570                 if (!dirent_is_file(de))
571                         continue;
572
573                 s = hashmap_get(m->seats, de->d_name);
574                 if (!s) {
575                         unlinkat(dirfd(d), de->d_name, 0);
576                         continue;
577                 }
578
579                 k = seat_load(s);
580                 if (k < 0)
581                         r = k;
582         }
583
584         return r;
585 }
586
587 static int manager_enumerate_linger_users(Manager *m) {
588         _cleanup_closedir_ DIR *d = NULL;
589         struct dirent *de;
590         int r = 0;
591
592         assert(m);
593
594         d = opendir("/var/lib/systemd/linger");
595         if (!d) {
596                 if (errno == ENOENT)
597                         return 0;
598
599                 log_error("Failed to open /var/lib/systemd/linger/: %m");
600                 return -errno;
601         }
602
603         FOREACH_DIRENT(de, d, return -errno) {
604                 int k;
605
606                 if (!dirent_is_file(de))
607                         continue;
608
609                 k = manager_add_user_by_name(m, de->d_name, NULL);
610                 if (k < 0) {
611                         log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
612                         r = k;
613                 }
614         }
615
616         return r;
617 }
618
619 int manager_enumerate_users(Manager *m) {
620         _cleanup_closedir_ DIR *d = NULL;
621         struct dirent *de;
622         int r, k;
623
624         assert(m);
625
626         /* Add lingering users */
627         r = manager_enumerate_linger_users(m);
628
629         /* Read in user data stored on disk */
630         d = opendir("/run/systemd/users");
631         if (!d) {
632                 if (errno == ENOENT)
633                         return 0;
634
635                 log_error("Failed to open /run/systemd/users: %m");
636                 return -errno;
637         }
638
639         FOREACH_DIRENT(de, d, return -errno) {
640                 User *u;
641
642                 if (!dirent_is_file(de))
643                         continue;
644
645                 k = manager_add_user_by_name(m, de->d_name, &u);
646                 if (k < 0) {
647                         log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
648
649                         r = k;
650                         continue;
651                 }
652
653                 user_add_to_gc_queue(u);
654
655                 k = user_load(u);
656                 if (k < 0)
657                         r = k;
658         }
659
660         return r;
661 }
662
663 int manager_enumerate_sessions(Manager *m) {
664         _cleanup_closedir_ DIR *d = NULL;
665         struct dirent *de;
666         int r = 0;
667
668         assert(m);
669
670         /* Read in session data stored on disk */
671         d = opendir("/run/systemd/sessions");
672         if (!d) {
673                 if (errno == ENOENT)
674                         return 0;
675
676                 log_error("Failed to open /run/systemd/sessions: %m");
677                 return -errno;
678         }
679
680         FOREACH_DIRENT(de, d, return -errno) {
681                 struct Session *s;
682                 int k;
683
684                 if (!dirent_is_file(de))
685                         continue;
686
687                 k = manager_add_session(m, de->d_name, &s);
688                 if (k < 0) {
689                         log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
690
691                         r = k;
692                         continue;
693                 }
694
695                 session_add_to_gc_queue(s);
696
697                 k = session_load(s);
698                 if (k < 0)
699                         r = k;
700         }
701
702         return r;
703 }
704
705 int manager_enumerate_inhibitors(Manager *m) {
706         _cleanup_closedir_ DIR *d = NULL;
707         struct dirent *de;
708         int r = 0;
709
710         assert(m);
711
712         d = opendir("/run/systemd/inhibit");
713         if (!d) {
714                 if (errno == ENOENT)
715                         return 0;
716
717                 log_error("Failed to open /run/systemd/inhibit: %m");
718                 return -errno;
719         }
720
721         FOREACH_DIRENT(de, d, return -errno) {
722                 int k;
723                 Inhibitor *i;
724
725                 if (!dirent_is_file(de))
726                         continue;
727
728                 k = manager_add_inhibitor(m, de->d_name, &i);
729                 if (k < 0) {
730                         log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
731                         r = k;
732                         continue;
733                 }
734
735                 k = inhibitor_load(i);
736                 if (k < 0)
737                         r = k;
738         }
739
740         return r;
741 }
742
743 int manager_dispatch_seat_udev(Manager *m) {
744         struct udev_device *d;
745         int r;
746
747         assert(m);
748
749         d = udev_monitor_receive_device(m->udev_seat_monitor);
750         if (!d)
751                 return -ENOMEM;
752
753         r = manager_process_seat_device(m, d);
754         udev_device_unref(d);
755
756         return r;
757 }
758
759 int manager_dispatch_vcsa_udev(Manager *m) {
760         struct udev_device *d;
761         int r = 0;
762         const char *name;
763
764         assert(m);
765
766         d = udev_monitor_receive_device(m->udev_vcsa_monitor);
767         if (!d)
768                 return -ENOMEM;
769
770         name = udev_device_get_sysname(d);
771
772         /* Whenever a VCSA device is removed try to reallocate our
773          * VTs, to make sure our auto VTs never go away. */
774
775         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
776                 r = seat_preallocate_vts(m->vtconsole);
777
778         udev_device_unref(d);
779
780         return r;
781 }
782
783 int manager_dispatch_button_udev(Manager *m) {
784         struct udev_device *d;
785         int r;
786
787         assert(m);
788
789         d = udev_monitor_receive_device(m->udev_button_monitor);
790         if (!d)
791                 return -ENOMEM;
792
793         r = manager_process_button_device(m, d);
794         udev_device_unref(d);
795
796         return r;
797 }
798
799 int manager_dispatch_console(Manager *m) {
800         assert(m);
801
802         if (m->vtconsole)
803                 seat_read_active_vt(m->vtconsole);
804
805         return 0;
806 }
807
808 static int vt_is_busy(int vtnr) {
809         struct vt_stat vt_stat;
810         int r = 0, fd;
811
812         assert(vtnr >= 1);
813
814         /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
815          * we'd open the latter we'd open the foreground tty which
816          * hence would be unconditionally busy. By opening /dev/tty1
817          * we avoid this. Since tty1 is special and needs to be an
818          * explicitly loaded getty or DM this is safe. */
819
820         fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
821         if (fd < 0)
822                 return -errno;
823
824         if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
825                 r = -errno;
826         else
827                 r = !!(vt_stat.v_state & (1 << vtnr));
828
829         close_nointr_nofail(fd);
830
831         return r;
832 }
833
834 int manager_spawn_autovt(Manager *m, int vtnr) {
835         int r;
836         char *name = NULL;
837         const char *mode = "fail";
838
839         assert(m);
840         assert(vtnr >= 1);
841
842         if ((unsigned) vtnr > m->n_autovts &&
843             (unsigned) vtnr != m->reserve_vt)
844                 return 0;
845
846         if ((unsigned) vtnr != m->reserve_vt) {
847                 /* If this is the reserved TTY, we'll start the getty
848                  * on it in any case, but otherwise only if it is not
849                  * busy. */
850
851                 r = vt_is_busy(vtnr);
852                 if (r < 0)
853                         return r;
854                 else if (r > 0)
855                         return -EBUSY;
856         }
857
858         if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
859                 log_error("Could not allocate service name.");
860                 r = -ENOMEM;
861                 goto finish;
862         }
863
864         r = bus_method_call_with_reply (
865                         m->bus,
866                         "org.freedesktop.systemd1",
867                         "/org/freedesktop/systemd1",
868                         "org.freedesktop.systemd1.Manager",
869                         "StartUnit",
870                         NULL,
871                         NULL,
872                         DBUS_TYPE_STRING, &name,
873                         DBUS_TYPE_STRING, &mode,
874                         DBUS_TYPE_INVALID);
875
876 finish:
877         free(name);
878
879         return r;
880 }
881
882 static int manager_reserve_vt(Manager *m) {
883         _cleanup_free_ char *p = NULL;
884
885         assert(m);
886
887         if (m->reserve_vt <= 0)
888                 return 0;
889
890         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
891                 return log_oom();
892
893         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
894         if (m->reserve_vt_fd < 0) {
895
896                 /* Don't complain on VT-less systems */
897                 if (errno != ENOENT)
898                         log_warning("Failed to pin reserved VT: %m");
899                 return -errno;
900         }
901
902         return 0;
903 }
904
905 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
906         _cleanup_free_ char *unit = NULL;
907         Session *s;
908         int r;
909
910         assert(m);
911         assert(pid >= 1);
912         assert(session);
913
914         r = cg_pid_get_unit(pid, &unit);
915         if (r < 0)
916                 return r;
917
918         s = hashmap_get(m->session_units, unit);
919         if (!s)
920                 return 0;
921
922         *session = s;
923         return 1;
924 }
925
926 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
927         _cleanup_free_ char *unit = NULL;
928         User *u;
929         int r;
930
931         assert(m);
932         assert(pid >= 1);
933         assert(user);
934
935         r = cg_pid_get_slice(pid, &unit);
936         if (r < 0)
937                 return r;
938
939         u = hashmap_get(m->user_units, unit);
940         if (!u)
941                 return 0;
942
943         *user = u;
944         return 1;
945 }
946
947 static void manager_dispatch_other(Manager *m, int fd) {
948         Session *s;
949         Inhibitor *i;
950         Button *b;
951
952         assert_se(m);
953         assert_se(fd >= 0);
954
955         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
956         if (s) {
957                 assert(s->fifo_fd == fd);
958                 session_remove_fifo(s);
959                 session_stop(s);
960                 return;
961         }
962
963         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
964         if (i) {
965                 assert(i->fifo_fd == fd);
966                 inhibitor_stop(i);
967                 inhibitor_free(i);
968                 return;
969         }
970
971         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
972         if (b) {
973                 assert(b->fd == fd);
974                 button_process(b);
975                 return;
976         }
977
978         assert_not_reached("Got event for unknown fd");
979 }
980
981 static int manager_connect_bus(Manager *m) {
982         DBusError error;
983         int r;
984         struct epoll_event ev = {
985                 .events = EPOLLIN,
986                 .data.u32 = FD_BUS,
987         };
988
989         assert(m);
990         assert(!m->bus);
991         assert(m->bus_fd < 0);
992
993         dbus_error_init(&error);
994
995         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
996         if (!m->bus) {
997                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
998                 r = -ECONNREFUSED;
999                 goto fail;
1000         }
1001
1002         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1003             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1004             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1005             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1006             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1007                 r = log_oom();
1008                 goto fail;
1009         }
1010
1011         dbus_bus_add_match(m->bus,
1012                            "type='signal',"
1013                            "sender='org.freedesktop.systemd1',"
1014                            "interface='org.freedesktop.systemd1.Manager',"
1015                            "member='JobRemoved',"
1016                            "path='/org/freedesktop/systemd1'",
1017                            &error);
1018         if (dbus_error_is_set(&error)) {
1019                 log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
1020                 dbus_error_free(&error);
1021         }
1022
1023         dbus_bus_add_match(m->bus,
1024                            "type='signal',"
1025                            "sender='org.freedesktop.systemd1',"
1026                            "interface='org.freedesktop.systemd1.Manager',"
1027                            "member='UnitRemoved',"
1028                            "path='/org/freedesktop/systemd1'",
1029                            &error);
1030         if (dbus_error_is_set(&error)) {
1031                 log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
1032                 dbus_error_free(&error);
1033         }
1034
1035         dbus_bus_add_match(m->bus,
1036                            "type='signal',"
1037                            "sender='org.freedesktop.systemd1',"
1038                            "interface='org.freedesktop.DBus.Properties',"
1039                            "member='PropertiesChanged'",
1040                            &error);
1041         if (dbus_error_is_set(&error)) {
1042                 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1043                 dbus_error_free(&error);
1044         }
1045
1046         dbus_bus_add_match(m->bus,
1047                            "type='signal',"
1048                            "sender='org.freedesktop.systemd1',"
1049                            "interface='org.freedesktop.systemd1.Manager',"
1050                            "member='Reloading',"
1051                            "path='/org/freedesktop/systemd1'",
1052                            &error);
1053         if (dbus_error_is_set(&error)) {
1054                 log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
1055                 dbus_error_free(&error);
1056         }
1057
1058         r = bus_method_call_with_reply(
1059                         m->bus,
1060                         "org.freedesktop.systemd1",
1061                         "/org/freedesktop/systemd1",
1062                         "org.freedesktop.systemd1.Manager",
1063                         "Subscribe",
1064                         NULL,
1065                         &error,
1066                         DBUS_TYPE_INVALID);
1067         if (r < 0) {
1068                 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1069                 dbus_error_free(&error);
1070         }
1071
1072         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1073         if (dbus_error_is_set(&error)) {
1074                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1075                 r = -EIO;
1076                 goto fail;
1077         }
1078
1079         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1080                 log_error("Failed to acquire name.");
1081                 r = -EEXIST;
1082                 goto fail;
1083         }
1084
1085         m->bus_fd = bus_loop_open(m->bus);
1086         if (m->bus_fd < 0) {
1087                 r = m->bus_fd;
1088                 goto fail;
1089         }
1090
1091         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1092                 goto fail;
1093
1094         return 0;
1095
1096 fail:
1097         dbus_error_free(&error);
1098
1099         return r;
1100 }
1101
1102 static int manager_connect_console(Manager *m) {
1103         struct epoll_event ev = {
1104                 .events = 0,
1105                 .data.u32 = FD_CONSOLE,
1106         };
1107
1108         assert(m);
1109         assert(m->console_active_fd < 0);
1110
1111         /* On certain architectures (S390 and Xen, and containers),
1112            /dev/tty0 does not exist, so don't fail if we can't open
1113            it. */
1114         if (access("/dev/tty0", F_OK) < 0) {
1115                 m->console_active_fd = -1;
1116                 return 0;
1117         }
1118
1119         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1120         if (m->console_active_fd < 0) {
1121
1122                 /* On some systems the device node /dev/tty0 may exist
1123                  * even though /sys/class/tty/tty0 does not. */
1124                 if (errno == ENOENT)
1125                         return 0;
1126
1127                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1128                 return -errno;
1129         }
1130
1131         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1132                 return -errno;
1133
1134         return 0;
1135 }
1136
1137 static int manager_connect_udev(Manager *m) {
1138         int r;
1139         struct epoll_event ev = {
1140                 .events = EPOLLIN,
1141                 .data.u32 = FD_SEAT_UDEV,
1142         };
1143
1144         assert(m);
1145         assert(!m->udev_seat_monitor);
1146         assert(!m->udev_vcsa_monitor);
1147         assert(!m->udev_button_monitor);
1148
1149         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1150         if (!m->udev_seat_monitor)
1151                 return -ENOMEM;
1152
1153         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1154         if (r < 0)
1155                 return r;
1156
1157         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1158         if (r < 0)
1159                 return r;
1160
1161         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1162
1163         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1164                 return -errno;
1165
1166         /* Don't watch keys if nobody cares */
1167         if (m->handle_power_key != HANDLE_IGNORE ||
1168             m->handle_suspend_key != HANDLE_IGNORE ||
1169             m->handle_hibernate_key != HANDLE_IGNORE ||
1170             m->handle_lid_switch != HANDLE_IGNORE) {
1171
1172                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1173                 if (!m->udev_button_monitor)
1174                         return -ENOMEM;
1175
1176                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1177                 if (r < 0)
1178                         return r;
1179
1180                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1181                 if (r < 0)
1182                         return r;
1183
1184                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1185                 if (r < 0)
1186                         return r;
1187
1188                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1189
1190                 zero(ev);
1191                 ev.events = EPOLLIN;
1192                 ev.data.u32 = FD_BUTTON_UDEV;
1193                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1194                         return -errno;
1195         }
1196
1197         /* Don't bother watching VCSA devices, if nobody cares */
1198         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1199
1200                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1201                 if (!m->udev_vcsa_monitor)
1202                         return -ENOMEM;
1203
1204                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1205                 if (r < 0)
1206                         return r;
1207
1208                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1209                 if (r < 0)
1210                         return r;
1211
1212                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1213
1214                 zero(ev);
1215                 ev.events = EPOLLIN;
1216                 ev.data.u32 = FD_VCSA_UDEV;
1217                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1218                         return -errno;
1219         }
1220
1221         return 0;
1222 }
1223
1224 void manager_gc(Manager *m, bool drop_not_started) {
1225         Seat *seat;
1226         Session *session;
1227         User *user;
1228
1229         assert(m);
1230
1231         while ((seat = m->seat_gc_queue)) {
1232                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1233                 seat->in_gc_queue = false;
1234
1235                 if (seat_check_gc(seat, drop_not_started) == 0) {
1236                         seat_stop(seat);
1237                         seat_free(seat);
1238                 }
1239         }
1240
1241         while ((session = m->session_gc_queue)) {
1242                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1243                 session->in_gc_queue = false;
1244
1245                 if (session_check_gc(session, drop_not_started) == 0) {
1246                         session_stop(session);
1247                         session_finalize(session);
1248                         session_free(session);
1249                 }
1250         }
1251
1252         while ((user = m->user_gc_queue)) {
1253                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1254                 user->in_gc_queue = false;
1255
1256                 if (user_check_gc(user, drop_not_started) == 0) {
1257                         user_stop(user);
1258                         user_finalize(user);
1259                         user_free(user);
1260                 }
1261         }
1262 }
1263
1264 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1265         Session *s;
1266         bool idle_hint;
1267         dual_timestamp ts = { 0, 0 };
1268         Iterator i;
1269
1270         assert(m);
1271
1272         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1273
1274         HASHMAP_FOREACH(s, m->sessions, i) {
1275                 dual_timestamp k;
1276                 int ih;
1277
1278                 ih = session_get_idle_hint(s, &k);
1279                 if (ih < 0)
1280                         return ih;
1281
1282                 if (!ih) {
1283                         if (!idle_hint) {
1284                                 if (k.monotonic < ts.monotonic)
1285                                         ts = k;
1286                         } else {
1287                                 idle_hint = false;
1288                                 ts = k;
1289                         }
1290                 } else if (idle_hint) {
1291
1292                         if (k.monotonic > ts.monotonic)
1293                                 ts = k;
1294                 }
1295         }
1296
1297         if (t)
1298                 *t = ts;
1299
1300         return idle_hint;
1301 }
1302
1303 bool manager_shall_kill(Manager *m, const char *user) {
1304         assert(m);
1305         assert(user);
1306
1307         if (!m->kill_user_processes)
1308                 return false;
1309
1310         if (strv_contains(m->kill_exclude_users, user))
1311                 return false;
1312
1313         if (strv_isempty(m->kill_only_users))
1314                 return true;
1315
1316         return strv_contains(m->kill_only_users, user);
1317 }
1318
1319 int manager_dispatch_idle_action(Manager *m) {
1320         struct dual_timestamp since;
1321         struct itimerspec its = {};
1322         int r;
1323         usec_t n;
1324
1325         assert(m);
1326
1327         if (m->idle_action == HANDLE_IGNORE ||
1328             m->idle_action_usec <= 0) {
1329                 r = 0;
1330                 goto finish;
1331         }
1332
1333         n = now(CLOCK_MONOTONIC);
1334
1335         r = manager_get_idle_hint(m, &since);
1336         if (r <= 0)
1337                 /* Not idle. Let's check if after a timeout it might be idle then. */
1338                 timespec_store(&its.it_value, n + m->idle_action_usec);
1339         else {
1340                 /* Idle! Let's see if it's time to do something, or if
1341                  * we shall sleep for longer. */
1342
1343                 if (n >= since.monotonic + m->idle_action_usec &&
1344                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1345                         log_info("System idle. Taking action.");
1346
1347                         manager_handle_action(m, 0, m->idle_action, false, false);
1348                         m->idle_action_not_before_usec = n;
1349                 }
1350
1351                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1352         }
1353
1354         if (m->idle_action_fd < 0) {
1355                 struct epoll_event ev = {
1356                         .events = EPOLLIN,
1357                         .data.u32 = FD_IDLE_ACTION,
1358                 };
1359
1360                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1361                 if (m->idle_action_fd < 0) {
1362                         log_error("Failed to create idle action timer: %m");
1363                         r = -errno;
1364                         goto finish;
1365                 }
1366
1367                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1368                         log_error("Failed to add idle action timer to epoll: %m");
1369                         r = -errno;
1370                         goto finish;
1371                 }
1372         }
1373
1374         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1375                 log_error("Failed to reset timerfd: %m");
1376                 r = -errno;
1377                 goto finish;
1378         }
1379
1380         return 0;
1381
1382 finish:
1383         if (m->idle_action_fd >= 0) {
1384                 close_nointr_nofail(m->idle_action_fd);
1385                 m->idle_action_fd = -1;
1386         }
1387
1388         return r;
1389 }
1390 int manager_startup(Manager *m) {
1391         int r;
1392         Seat *seat;
1393         Session *session;
1394         User *user;
1395         Inhibitor *inhibitor;
1396         Iterator i;
1397
1398         assert(m);
1399         assert(m->epoll_fd <= 0);
1400
1401         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1402         if (m->epoll_fd < 0)
1403                 return -errno;
1404
1405         /* Connect to console */
1406         r = manager_connect_console(m);
1407         if (r < 0)
1408                 return r;
1409
1410         /* Connect to udev */
1411         r = manager_connect_udev(m);
1412         if (r < 0)
1413                 return r;
1414
1415         /* Connect to the bus */
1416         r = manager_connect_bus(m);
1417         if (r < 0)
1418                 return r;
1419
1420         /* Instantiate magic seat 0 */
1421         r = manager_add_seat(m, "seat0", &m->vtconsole);
1422         if (r < 0)
1423                 return r;
1424
1425         /* Deserialize state */
1426         manager_enumerate_devices(m);
1427         manager_enumerate_seats(m);
1428         manager_enumerate_users(m);
1429         manager_enumerate_sessions(m);
1430         manager_enumerate_inhibitors(m);
1431         manager_enumerate_buttons(m);
1432
1433         /* Remove stale objects before we start them */
1434         manager_gc(m, false);
1435
1436         /* Reserve the special reserved VT */
1437         manager_reserve_vt(m);
1438
1439         /* And start everything */
1440         HASHMAP_FOREACH(seat, m->seats, i)
1441                 seat_start(seat);
1442
1443         HASHMAP_FOREACH(user, m->users, i)
1444                 user_start(user);
1445
1446         HASHMAP_FOREACH(session, m->sessions, i)
1447                 session_start(session);
1448
1449         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1450                 inhibitor_start(inhibitor);
1451
1452         manager_dispatch_idle_action(m);
1453
1454         return 0;
1455 }
1456
1457 static int manager_recheck_buttons(Manager *m) {
1458         Iterator i;
1459         Button *b;
1460         int r = 0;
1461
1462         assert(m);
1463
1464         HASHMAP_FOREACH(b, m->buttons, i) {
1465                 int q;
1466
1467                 q = button_recheck(b);
1468                 if (q > 0)
1469                         return 1;
1470                 if (q < 0)
1471                         r = q;
1472         }
1473
1474         return r;
1475 }
1476
1477 int manager_run(Manager *m) {
1478         assert(m);
1479
1480         for (;;) {
1481                 struct epoll_event event;
1482                 int n;
1483                 int msec = -1;
1484
1485                 manager_gc(m, true);
1486
1487                 if (manager_dispatch_delayed(m) > 0)
1488                         continue;
1489
1490                 if (manager_recheck_buttons(m) > 0)
1491                         continue;
1492
1493                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1494                         continue;
1495
1496                 manager_gc(m, true);
1497
1498                 if (m->action_what != 0 && !m->action_job) {
1499                         usec_t x, y;
1500
1501                         x = now(CLOCK_MONOTONIC);
1502                         y = m->action_timestamp + m->inhibit_delay_max;
1503
1504                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1505                 }
1506
1507                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1508                 if (n < 0) {
1509                         if (errno == EINTR || errno == EAGAIN)
1510                                 continue;
1511
1512                         log_error("epoll() failed: %m");
1513                         return -errno;
1514                 }
1515
1516                 if (n == 0)
1517                         continue;
1518
1519                 switch (event.data.u32) {
1520
1521                 case FD_SEAT_UDEV:
1522                         manager_dispatch_seat_udev(m);
1523                         break;
1524
1525                 case FD_VCSA_UDEV:
1526                         manager_dispatch_vcsa_udev(m);
1527                         break;
1528
1529                 case FD_BUTTON_UDEV:
1530                         manager_dispatch_button_udev(m);
1531                         break;
1532
1533                 case FD_CONSOLE:
1534                         manager_dispatch_console(m);
1535                         break;
1536
1537                 case FD_IDLE_ACTION:
1538                         manager_dispatch_idle_action(m);
1539                         break;
1540
1541                 case FD_BUS:
1542                         bus_loop_dispatch(m->bus_fd);
1543                         break;
1544
1545                 default:
1546                         if (event.data.u32 >= FD_OTHER_BASE)
1547                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1548                 }
1549         }
1550
1551         return 0;
1552 }
1553
1554 static int manager_parse_config_file(Manager *m) {
1555         static const char fn[] = "/etc/systemd/logind.conf";
1556         _cleanup_fclose_ FILE *f = NULL;
1557         int r;
1558
1559         assert(m);
1560
1561         f = fopen(fn, "re");
1562         if (!f) {
1563                 if (errno == ENOENT)
1564                         return 0;
1565
1566                 log_warning("Failed to open configuration file %s: %m", fn);
1567                 return -errno;
1568         }
1569
1570         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1571                          (void*) logind_gperf_lookup, false, false, m);
1572         if (r < 0)
1573                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1574
1575         return r;
1576 }
1577
1578 int main(int argc, char *argv[]) {
1579         Manager *m = NULL;
1580         int r;
1581
1582         log_set_target(LOG_TARGET_AUTO);
1583         log_set_facility(LOG_AUTH);
1584         log_parse_environment();
1585         log_open();
1586
1587         umask(0022);
1588
1589         if (argc != 1) {
1590                 log_error("This program takes no arguments.");
1591                 r = -EINVAL;
1592                 goto finish;
1593         }
1594
1595         /* Always create the directories people can create inotify
1596          * watches in. Note that some applications might check for the
1597          * existence of /run/systemd/seats/ to determine whether
1598          * logind is available, so please always make sure this check
1599          * stays in. */
1600         mkdir_label("/run/systemd/seats", 0755);
1601         mkdir_label("/run/systemd/users", 0755);
1602         mkdir_label("/run/systemd/sessions", 0755);
1603
1604         m = manager_new();
1605         if (!m) {
1606                 r = log_oom();
1607                 goto finish;
1608         }
1609
1610         manager_parse_config_file(m);
1611
1612         r = manager_startup(m);
1613         if (r < 0) {
1614                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1615                 goto finish;
1616         }
1617
1618         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1619
1620         sd_notify(false,
1621                   "READY=1\n"
1622                   "STATUS=Processing requests...");
1623
1624         r = manager_run(m);
1625
1626         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1627
1628 finish:
1629         sd_notify(false,
1630                   "STATUS=Shutting down...");
1631
1632         if (m)
1633                 manager_free(m);
1634
1635         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1636 }