chiark / gitweb /
fcb3ccf4a5e5de3faca3134077e13b56e5a6a498
[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
1042         if (dbus_error_is_set(&error)) {
1043                 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1044                 dbus_error_free(&error);
1045         }
1046
1047         r = bus_method_call_with_reply(
1048                         m->bus,
1049                         "org.freedesktop.systemd1",
1050                         "/org/freedesktop/systemd1",
1051                         "org.freedesktop.systemd1.Manager",
1052                         "Subscribe",
1053                         NULL,
1054                         &error,
1055                         DBUS_TYPE_INVALID);
1056         if (r < 0) {
1057                 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1058                 dbus_error_free(&error);
1059         }
1060
1061         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1062         if (dbus_error_is_set(&error)) {
1063                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1064                 r = -EIO;
1065                 goto fail;
1066         }
1067
1068         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1069                 log_error("Failed to acquire name.");
1070                 r = -EEXIST;
1071                 goto fail;
1072         }
1073
1074         m->bus_fd = bus_loop_open(m->bus);
1075         if (m->bus_fd < 0) {
1076                 r = m->bus_fd;
1077                 goto fail;
1078         }
1079
1080         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1081                 goto fail;
1082
1083         return 0;
1084
1085 fail:
1086         dbus_error_free(&error);
1087
1088         return r;
1089 }
1090
1091 static int manager_connect_console(Manager *m) {
1092         struct epoll_event ev = {
1093                 .events = 0,
1094                 .data.u32 = FD_CONSOLE,
1095         };
1096
1097         assert(m);
1098         assert(m->console_active_fd < 0);
1099
1100         /* On certain architectures (S390 and Xen, and containers),
1101            /dev/tty0 does not exist, so don't fail if we can't open
1102            it. */
1103         if (access("/dev/tty0", F_OK) < 0) {
1104                 m->console_active_fd = -1;
1105                 return 0;
1106         }
1107
1108         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1109         if (m->console_active_fd < 0) {
1110
1111                 /* On some systems the device node /dev/tty0 may exist
1112                  * even though /sys/class/tty/tty0 does not. */
1113                 if (errno == ENOENT)
1114                         return 0;
1115
1116                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1117                 return -errno;
1118         }
1119
1120         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1121                 return -errno;
1122
1123         return 0;
1124 }
1125
1126 static int manager_connect_udev(Manager *m) {
1127         int r;
1128         struct epoll_event ev = {
1129                 .events = EPOLLIN,
1130                 .data.u32 = FD_SEAT_UDEV,
1131         };
1132
1133         assert(m);
1134         assert(!m->udev_seat_monitor);
1135         assert(!m->udev_vcsa_monitor);
1136         assert(!m->udev_button_monitor);
1137
1138         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1139         if (!m->udev_seat_monitor)
1140                 return -ENOMEM;
1141
1142         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1143         if (r < 0)
1144                 return r;
1145
1146         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1147         if (r < 0)
1148                 return r;
1149
1150         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1151
1152         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1153                 return -errno;
1154
1155         /* Don't watch keys if nobody cares */
1156         if (m->handle_power_key != HANDLE_IGNORE ||
1157             m->handle_suspend_key != HANDLE_IGNORE ||
1158             m->handle_hibernate_key != HANDLE_IGNORE ||
1159             m->handle_lid_switch != HANDLE_IGNORE) {
1160
1161                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1162                 if (!m->udev_button_monitor)
1163                         return -ENOMEM;
1164
1165                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1166                 if (r < 0)
1167                         return r;
1168
1169                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1170                 if (r < 0)
1171                         return r;
1172
1173                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1174                 if (r < 0)
1175                         return r;
1176
1177                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1178
1179                 zero(ev);
1180                 ev.events = EPOLLIN;
1181                 ev.data.u32 = FD_BUTTON_UDEV;
1182                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1183                         return -errno;
1184         }
1185
1186         /* Don't bother watching VCSA devices, if nobody cares */
1187         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1188
1189                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1190                 if (!m->udev_vcsa_monitor)
1191                         return -ENOMEM;
1192
1193                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1194                 if (r < 0)
1195                         return r;
1196
1197                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1198                 if (r < 0)
1199                         return r;
1200
1201                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1202
1203                 zero(ev);
1204                 ev.events = EPOLLIN;
1205                 ev.data.u32 = FD_VCSA_UDEV;
1206                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1207                         return -errno;
1208         }
1209
1210         return 0;
1211 }
1212
1213 void manager_gc(Manager *m, bool drop_not_started) {
1214         Seat *seat;
1215         Session *session;
1216         User *user;
1217
1218         assert(m);
1219
1220         while ((seat = m->seat_gc_queue)) {
1221                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1222                 seat->in_gc_queue = false;
1223
1224                 if (seat_check_gc(seat, drop_not_started) == 0) {
1225                         seat_stop(seat);
1226                         seat_free(seat);
1227                 }
1228         }
1229
1230         while ((session = m->session_gc_queue)) {
1231                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1232                 session->in_gc_queue = false;
1233
1234                 if (session_check_gc(session, drop_not_started) == 0) {
1235                         session_stop(session);
1236                         session_free(session);
1237                 }
1238         }
1239
1240         while ((user = m->user_gc_queue)) {
1241                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1242                 user->in_gc_queue = false;
1243
1244                 if (user_check_gc(user, drop_not_started) == 0) {
1245                         user_stop(user);
1246                         user_free(user);
1247                 }
1248         }
1249 }
1250
1251 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1252         Session *s;
1253         bool idle_hint;
1254         dual_timestamp ts = { 0, 0 };
1255         Iterator i;
1256
1257         assert(m);
1258
1259         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1260
1261         HASHMAP_FOREACH(s, m->sessions, i) {
1262                 dual_timestamp k;
1263                 int ih;
1264
1265                 ih = session_get_idle_hint(s, &k);
1266                 if (ih < 0)
1267                         return ih;
1268
1269                 if (!ih) {
1270                         if (!idle_hint) {
1271                                 if (k.monotonic < ts.monotonic)
1272                                         ts = k;
1273                         } else {
1274                                 idle_hint = false;
1275                                 ts = k;
1276                         }
1277                 } else if (idle_hint) {
1278
1279                         if (k.monotonic > ts.monotonic)
1280                                 ts = k;
1281                 }
1282         }
1283
1284         if (t)
1285                 *t = ts;
1286
1287         return idle_hint;
1288 }
1289
1290 int manager_dispatch_idle_action(Manager *m) {
1291         struct dual_timestamp since;
1292         struct itimerspec its = {};
1293         int r;
1294         usec_t n;
1295
1296         assert(m);
1297
1298         if (m->idle_action == HANDLE_IGNORE ||
1299             m->idle_action_usec <= 0) {
1300                 r = 0;
1301                 goto finish;
1302         }
1303
1304         n = now(CLOCK_MONOTONIC);
1305
1306         r = manager_get_idle_hint(m, &since);
1307         if (r <= 0)
1308                 /* Not idle. Let's check if after a timeout it might be idle then. */
1309                 timespec_store(&its.it_value, n + m->idle_action_usec);
1310         else {
1311                 /* Idle! Let's see if it's time to do something, or if
1312                  * we shall sleep for longer. */
1313
1314                 if (n >= since.monotonic + m->idle_action_usec &&
1315                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1316                         log_info("System idle. Taking action.");
1317
1318                         manager_handle_action(m, 0, m->idle_action, false, false);
1319                         m->idle_action_not_before_usec = n;
1320                 }
1321
1322                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1323         }
1324
1325         if (m->idle_action_fd < 0) {
1326                 struct epoll_event ev = {
1327                         .events = EPOLLIN,
1328                         .data.u32 = FD_IDLE_ACTION,
1329                 };
1330
1331                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1332                 if (m->idle_action_fd < 0) {
1333                         log_error("Failed to create idle action timer: %m");
1334                         r = -errno;
1335                         goto finish;
1336                 }
1337
1338                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1339                         log_error("Failed to add idle action timer to epoll: %m");
1340                         r = -errno;
1341                         goto finish;
1342                 }
1343         }
1344
1345         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1346                 log_error("Failed to reset timerfd: %m");
1347                 r = -errno;
1348                 goto finish;
1349         }
1350
1351         return 0;
1352
1353 finish:
1354         if (m->idle_action_fd >= 0) {
1355                 close_nointr_nofail(m->idle_action_fd);
1356                 m->idle_action_fd = -1;
1357         }
1358
1359         return r;
1360 }
1361 int manager_startup(Manager *m) {
1362         int r;
1363         Seat *seat;
1364         Session *session;
1365         User *user;
1366         Inhibitor *inhibitor;
1367         Iterator i;
1368
1369         assert(m);
1370         assert(m->epoll_fd <= 0);
1371
1372         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1373         if (m->epoll_fd < 0)
1374                 return -errno;
1375
1376         /* Connect to console */
1377         r = manager_connect_console(m);
1378         if (r < 0)
1379                 return r;
1380
1381         /* Connect to udev */
1382         r = manager_connect_udev(m);
1383         if (r < 0)
1384                 return r;
1385
1386         /* Connect to the bus */
1387         r = manager_connect_bus(m);
1388         if (r < 0)
1389                 return r;
1390
1391         /* Instantiate magic seat 0 */
1392         r = manager_add_seat(m, "seat0", &m->vtconsole);
1393         if (r < 0)
1394                 return r;
1395
1396         /* Deserialize state */
1397         manager_enumerate_devices(m);
1398         manager_enumerate_seats(m);
1399         manager_enumerate_users(m);
1400         manager_enumerate_sessions(m);
1401         manager_enumerate_inhibitors(m);
1402         manager_enumerate_buttons(m);
1403
1404         /* Remove stale objects before we start them */
1405         manager_gc(m, false);
1406
1407         /* Reserve the special reserved VT */
1408         manager_reserve_vt(m);
1409
1410         /* And start everything */
1411         HASHMAP_FOREACH(seat, m->seats, i)
1412                 seat_start(seat);
1413
1414         HASHMAP_FOREACH(user, m->users, i)
1415                 user_start(user);
1416
1417         HASHMAP_FOREACH(session, m->sessions, i)
1418                 session_start(session);
1419
1420         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1421                 inhibitor_start(inhibitor);
1422
1423         manager_dispatch_idle_action(m);
1424
1425         return 0;
1426 }
1427
1428 static int manager_recheck_buttons(Manager *m) {
1429         Iterator i;
1430         Button *b;
1431         int r = 0;
1432
1433         assert(m);
1434
1435         HASHMAP_FOREACH(b, m->buttons, i) {
1436                 int q;
1437
1438                 q = button_recheck(b);
1439                 if (q > 0)
1440                         return 1;
1441                 if (q < 0)
1442                         r = q;
1443         }
1444
1445         return r;
1446 }
1447
1448 int manager_run(Manager *m) {
1449         assert(m);
1450
1451         for (;;) {
1452                 struct epoll_event event;
1453                 int n;
1454                 int msec = -1;
1455
1456                 manager_gc(m, true);
1457
1458                 if (manager_dispatch_delayed(m) > 0)
1459                         continue;
1460
1461                 if (manager_recheck_buttons(m) > 0)
1462                         continue;
1463
1464                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1465                         continue;
1466
1467                 manager_gc(m, true);
1468
1469                 if (m->action_what != 0 && !m->action_job) {
1470                         usec_t x, y;
1471
1472                         x = now(CLOCK_MONOTONIC);
1473                         y = m->action_timestamp + m->inhibit_delay_max;
1474
1475                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1476                 }
1477
1478                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1479                 if (n < 0) {
1480                         if (errno == EINTR || errno == EAGAIN)
1481                                 continue;
1482
1483                         log_error("epoll() failed: %m");
1484                         return -errno;
1485                 }
1486
1487                 if (n == 0)
1488                         continue;
1489
1490                 switch (event.data.u32) {
1491
1492                 case FD_SEAT_UDEV:
1493                         manager_dispatch_seat_udev(m);
1494                         break;
1495
1496                 case FD_VCSA_UDEV:
1497                         manager_dispatch_vcsa_udev(m);
1498                         break;
1499
1500                 case FD_BUTTON_UDEV:
1501                         manager_dispatch_button_udev(m);
1502                         break;
1503
1504                 case FD_CONSOLE:
1505                         manager_dispatch_console(m);
1506                         break;
1507
1508                 case FD_IDLE_ACTION:
1509                         manager_dispatch_idle_action(m);
1510                         break;
1511
1512                 case FD_BUS:
1513                         bus_loop_dispatch(m->bus_fd);
1514                         break;
1515
1516                 default:
1517                         if (event.data.u32 >= FD_OTHER_BASE)
1518                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1519                 }
1520         }
1521
1522         return 0;
1523 }
1524
1525 static int manager_parse_config_file(Manager *m) {
1526         static const char fn[] = "/etc/systemd/logind.conf";
1527         _cleanup_fclose_ FILE *f = NULL;
1528         int r;
1529
1530         assert(m);
1531
1532         f = fopen(fn, "re");
1533         if (!f) {
1534                 if (errno == ENOENT)
1535                         return 0;
1536
1537                 log_warning("Failed to open configuration file %s: %m", fn);
1538                 return -errno;
1539         }
1540
1541         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1542                          (void*) logind_gperf_lookup, false, false, m);
1543         if (r < 0)
1544                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1545
1546         return r;
1547 }
1548
1549 int main(int argc, char *argv[]) {
1550         Manager *m = NULL;
1551         int r;
1552
1553         log_set_target(LOG_TARGET_AUTO);
1554         log_set_facility(LOG_AUTH);
1555         log_parse_environment();
1556         log_open();
1557
1558         umask(0022);
1559
1560         if (argc != 1) {
1561                 log_error("This program takes no arguments.");
1562                 r = -EINVAL;
1563                 goto finish;
1564         }
1565
1566         /* Always create the directories people can create inotify
1567          * watches in. Note that some applications might check for the
1568          * existence of /run/systemd/seats/ to determine whether
1569          * logind is available, so please always make sure this check
1570          * stays in. */
1571         mkdir_label("/run/systemd/seats", 0755);
1572         mkdir_label("/run/systemd/users", 0755);
1573         mkdir_label("/run/systemd/sessions", 0755);
1574
1575         m = manager_new();
1576         if (!m) {
1577                 r = log_oom();
1578                 goto finish;
1579         }
1580
1581         manager_parse_config_file(m);
1582
1583         r = manager_startup(m);
1584         if (r < 0) {
1585                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1586                 goto finish;
1587         }
1588
1589         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1590
1591         sd_notify(false,
1592                   "READY=1\n"
1593                   "STATUS=Processing requests...");
1594
1595         r = manager_run(m);
1596
1597         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1598
1599 finish:
1600         sd_notify(false,
1601                   "STATUS=Shutting down...");
1602
1603         if (m)
1604                 manager_free(m);
1605
1606         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1607 }