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