chiark / gitweb /
Verify validity of session name when received from outside
[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                 if (!session_id_valid(de->d_name)) {
688                         log_warning("Invalid session file name '%s', ignoring.", de->d_name);
689                         r = -EINVAL;
690                         continue;
691                 }
692
693                 k = manager_add_session(m, de->d_name, &s);
694                 if (k < 0) {
695                         log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
696
697                         r = k;
698                         continue;
699                 }
700
701                 session_add_to_gc_queue(s);
702
703                 k = session_load(s);
704                 if (k < 0)
705                         r = k;
706         }
707
708         return r;
709 }
710
711 int manager_enumerate_inhibitors(Manager *m) {
712         _cleanup_closedir_ DIR *d = NULL;
713         struct dirent *de;
714         int r = 0;
715
716         assert(m);
717
718         d = opendir("/run/systemd/inhibit");
719         if (!d) {
720                 if (errno == ENOENT)
721                         return 0;
722
723                 log_error("Failed to open /run/systemd/inhibit: %m");
724                 return -errno;
725         }
726
727         FOREACH_DIRENT(de, d, return -errno) {
728                 int k;
729                 Inhibitor *i;
730
731                 if (!dirent_is_file(de))
732                         continue;
733
734                 k = manager_add_inhibitor(m, de->d_name, &i);
735                 if (k < 0) {
736                         log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
737                         r = k;
738                         continue;
739                 }
740
741                 k = inhibitor_load(i);
742                 if (k < 0)
743                         r = k;
744         }
745
746         return r;
747 }
748
749 int manager_dispatch_seat_udev(Manager *m) {
750         struct udev_device *d;
751         int r;
752
753         assert(m);
754
755         d = udev_monitor_receive_device(m->udev_seat_monitor);
756         if (!d)
757                 return -ENOMEM;
758
759         r = manager_process_seat_device(m, d);
760         udev_device_unref(d);
761
762         return r;
763 }
764
765 int manager_dispatch_vcsa_udev(Manager *m) {
766         struct udev_device *d;
767         int r = 0;
768         const char *name;
769
770         assert(m);
771
772         d = udev_monitor_receive_device(m->udev_vcsa_monitor);
773         if (!d)
774                 return -ENOMEM;
775
776         name = udev_device_get_sysname(d);
777
778         /* Whenever a VCSA device is removed try to reallocate our
779          * VTs, to make sure our auto VTs never go away. */
780
781         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
782                 r = seat_preallocate_vts(m->vtconsole);
783
784         udev_device_unref(d);
785
786         return r;
787 }
788
789 int manager_dispatch_button_udev(Manager *m) {
790         struct udev_device *d;
791         int r;
792
793         assert(m);
794
795         d = udev_monitor_receive_device(m->udev_button_monitor);
796         if (!d)
797                 return -ENOMEM;
798
799         r = manager_process_button_device(m, d);
800         udev_device_unref(d);
801
802         return r;
803 }
804
805 int manager_dispatch_console(Manager *m) {
806         assert(m);
807
808         if (m->vtconsole)
809                 seat_read_active_vt(m->vtconsole);
810
811         return 0;
812 }
813
814 static int vt_is_busy(int vtnr) {
815         struct vt_stat vt_stat;
816         int r = 0, fd;
817
818         assert(vtnr >= 1);
819
820         /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
821          * we'd open the latter we'd open the foreground tty which
822          * hence would be unconditionally busy. By opening /dev/tty1
823          * we avoid this. Since tty1 is special and needs to be an
824          * explicitly loaded getty or DM this is safe. */
825
826         fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
827         if (fd < 0)
828                 return -errno;
829
830         if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
831                 r = -errno;
832         else
833                 r = !!(vt_stat.v_state & (1 << vtnr));
834
835         close_nointr_nofail(fd);
836
837         return r;
838 }
839
840 int manager_spawn_autovt(Manager *m, int vtnr) {
841         int r;
842         char *name = NULL;
843         const char *mode = "fail";
844
845         assert(m);
846         assert(vtnr >= 1);
847
848         if ((unsigned) vtnr > m->n_autovts &&
849             (unsigned) vtnr != m->reserve_vt)
850                 return 0;
851
852         if ((unsigned) vtnr != m->reserve_vt) {
853                 /* If this is the reserved TTY, we'll start the getty
854                  * on it in any case, but otherwise only if it is not
855                  * busy. */
856
857                 r = vt_is_busy(vtnr);
858                 if (r < 0)
859                         return r;
860                 else if (r > 0)
861                         return -EBUSY;
862         }
863
864         if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
865                 log_error("Could not allocate service name.");
866                 r = -ENOMEM;
867                 goto finish;
868         }
869
870         r = bus_method_call_with_reply (
871                         m->bus,
872                         "org.freedesktop.systemd1",
873                         "/org/freedesktop/systemd1",
874                         "org.freedesktop.systemd1.Manager",
875                         "StartUnit",
876                         NULL,
877                         NULL,
878                         DBUS_TYPE_STRING, &name,
879                         DBUS_TYPE_STRING, &mode,
880                         DBUS_TYPE_INVALID);
881
882 finish:
883         free(name);
884
885         return r;
886 }
887
888 static int manager_reserve_vt(Manager *m) {
889         _cleanup_free_ char *p = NULL;
890
891         assert(m);
892
893         if (m->reserve_vt <= 0)
894                 return 0;
895
896         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
897                 return log_oom();
898
899         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
900         if (m->reserve_vt_fd < 0) {
901
902                 /* Don't complain on VT-less systems */
903                 if (errno != ENOENT)
904                         log_warning("Failed to pin reserved VT: %m");
905                 return -errno;
906         }
907
908         return 0;
909 }
910
911 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
912         _cleanup_free_ char *unit = NULL;
913         Session *s;
914         int r;
915
916         assert(m);
917         assert(pid >= 1);
918         assert(session);
919
920         r = cg_pid_get_unit(pid, &unit);
921         if (r < 0)
922                 return r;
923
924         s = hashmap_get(m->session_units, unit);
925         if (!s)
926                 return 0;
927
928         *session = s;
929         return 1;
930 }
931
932 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
933         _cleanup_free_ char *unit = NULL;
934         User *u;
935         int r;
936
937         assert(m);
938         assert(pid >= 1);
939         assert(user);
940
941         r = cg_pid_get_slice(pid, &unit);
942         if (r < 0)
943                 return r;
944
945         u = hashmap_get(m->user_units, unit);
946         if (!u)
947                 return 0;
948
949         *user = u;
950         return 1;
951 }
952
953 static void manager_dispatch_other(Manager *m, int fd) {
954         Session *s;
955         Inhibitor *i;
956         Button *b;
957
958         assert_se(m);
959         assert_se(fd >= 0);
960
961         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
962         if (s) {
963                 assert(s->fifo_fd == fd);
964                 session_remove_fifo(s);
965                 session_stop(s);
966                 return;
967         }
968
969         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
970         if (i) {
971                 assert(i->fifo_fd == fd);
972                 inhibitor_stop(i);
973                 inhibitor_free(i);
974                 return;
975         }
976
977         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
978         if (b) {
979                 assert(b->fd == fd);
980                 button_process(b);
981                 return;
982         }
983
984         assert_not_reached("Got event for unknown fd");
985 }
986
987 static int manager_connect_bus(Manager *m) {
988         DBusError error;
989         int r;
990         struct epoll_event ev = {
991                 .events = EPOLLIN,
992                 .data.u32 = FD_BUS,
993         };
994
995         assert(m);
996         assert(!m->bus);
997         assert(m->bus_fd < 0);
998
999         dbus_error_init(&error);
1000
1001         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1002         if (!m->bus) {
1003                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1004                 r = -ECONNREFUSED;
1005                 goto fail;
1006         }
1007
1008         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1009             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1010             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1011             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1012             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1013                 r = log_oom();
1014                 goto fail;
1015         }
1016
1017         dbus_bus_add_match(m->bus,
1018                            "type='signal',"
1019                            "sender='org.freedesktop.systemd1',"
1020                            "interface='org.freedesktop.systemd1.Manager',"
1021                            "member='JobRemoved',"
1022                            "path='/org/freedesktop/systemd1'",
1023                            &error);
1024         if (dbus_error_is_set(&error)) {
1025                 log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
1026                 dbus_error_free(&error);
1027         }
1028
1029         dbus_bus_add_match(m->bus,
1030                            "type='signal',"
1031                            "sender='org.freedesktop.systemd1',"
1032                            "interface='org.freedesktop.systemd1.Manager',"
1033                            "member='UnitRemoved',"
1034                            "path='/org/freedesktop/systemd1'",
1035                            &error);
1036         if (dbus_error_is_set(&error)) {
1037                 log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
1038                 dbus_error_free(&error);
1039         }
1040
1041         dbus_bus_add_match(m->bus,
1042                            "type='signal',"
1043                            "sender='org.freedesktop.systemd1',"
1044                            "interface='org.freedesktop.DBus.Properties',"
1045                            "member='PropertiesChanged'",
1046                            &error);
1047         if (dbus_error_is_set(&error)) {
1048                 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1049                 dbus_error_free(&error);
1050         }
1051
1052         dbus_bus_add_match(m->bus,
1053                            "type='signal',"
1054                            "sender='org.freedesktop.systemd1',"
1055                            "interface='org.freedesktop.systemd1.Manager',"
1056                            "member='Reloading',"
1057                            "path='/org/freedesktop/systemd1'",
1058                            &error);
1059         if (dbus_error_is_set(&error)) {
1060                 log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
1061                 dbus_error_free(&error);
1062         }
1063
1064         r = bus_method_call_with_reply(
1065                         m->bus,
1066                         "org.freedesktop.systemd1",
1067                         "/org/freedesktop/systemd1",
1068                         "org.freedesktop.systemd1.Manager",
1069                         "Subscribe",
1070                         NULL,
1071                         &error,
1072                         DBUS_TYPE_INVALID);
1073         if (r < 0) {
1074                 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1075                 dbus_error_free(&error);
1076         }
1077
1078         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1079         if (dbus_error_is_set(&error)) {
1080                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1081                 r = -EIO;
1082                 goto fail;
1083         }
1084
1085         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1086                 log_error("Failed to acquire name.");
1087                 r = -EEXIST;
1088                 goto fail;
1089         }
1090
1091         m->bus_fd = bus_loop_open(m->bus);
1092         if (m->bus_fd < 0) {
1093                 r = m->bus_fd;
1094                 goto fail;
1095         }
1096
1097         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1098                 goto fail;
1099
1100         return 0;
1101
1102 fail:
1103         dbus_error_free(&error);
1104
1105         return r;
1106 }
1107
1108 static int manager_connect_console(Manager *m) {
1109         struct epoll_event ev = {
1110                 .events = 0,
1111                 .data.u32 = FD_CONSOLE,
1112         };
1113
1114         assert(m);
1115         assert(m->console_active_fd < 0);
1116
1117         /* On certain architectures (S390 and Xen, and containers),
1118            /dev/tty0 does not exist, so don't fail if we can't open
1119            it. */
1120         if (access("/dev/tty0", F_OK) < 0) {
1121                 m->console_active_fd = -1;
1122                 return 0;
1123         }
1124
1125         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1126         if (m->console_active_fd < 0) {
1127
1128                 /* On some systems the device node /dev/tty0 may exist
1129                  * even though /sys/class/tty/tty0 does not. */
1130                 if (errno == ENOENT)
1131                         return 0;
1132
1133                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1134                 return -errno;
1135         }
1136
1137         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1138                 return -errno;
1139
1140         return 0;
1141 }
1142
1143 static int manager_connect_udev(Manager *m) {
1144         int r;
1145         struct epoll_event ev = {
1146                 .events = EPOLLIN,
1147                 .data.u32 = FD_SEAT_UDEV,
1148         };
1149
1150         assert(m);
1151         assert(!m->udev_seat_monitor);
1152         assert(!m->udev_vcsa_monitor);
1153         assert(!m->udev_button_monitor);
1154
1155         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1156         if (!m->udev_seat_monitor)
1157                 return -ENOMEM;
1158
1159         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1160         if (r < 0)
1161                 return r;
1162
1163         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1164         if (r < 0)
1165                 return r;
1166
1167         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1168
1169         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1170                 return -errno;
1171
1172         /* Don't watch keys if nobody cares */
1173         if (m->handle_power_key != HANDLE_IGNORE ||
1174             m->handle_suspend_key != HANDLE_IGNORE ||
1175             m->handle_hibernate_key != HANDLE_IGNORE ||
1176             m->handle_lid_switch != HANDLE_IGNORE) {
1177
1178                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1179                 if (!m->udev_button_monitor)
1180                         return -ENOMEM;
1181
1182                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1183                 if (r < 0)
1184                         return r;
1185
1186                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1187                 if (r < 0)
1188                         return r;
1189
1190                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1191                 if (r < 0)
1192                         return r;
1193
1194                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1195
1196                 zero(ev);
1197                 ev.events = EPOLLIN;
1198                 ev.data.u32 = FD_BUTTON_UDEV;
1199                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1200                         return -errno;
1201         }
1202
1203         /* Don't bother watching VCSA devices, if nobody cares */
1204         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1205
1206                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1207                 if (!m->udev_vcsa_monitor)
1208                         return -ENOMEM;
1209
1210                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1211                 if (r < 0)
1212                         return r;
1213
1214                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1215                 if (r < 0)
1216                         return r;
1217
1218                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1219
1220                 zero(ev);
1221                 ev.events = EPOLLIN;
1222                 ev.data.u32 = FD_VCSA_UDEV;
1223                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1224                         return -errno;
1225         }
1226
1227         return 0;
1228 }
1229
1230 void manager_gc(Manager *m, bool drop_not_started) {
1231         Seat *seat;
1232         Session *session;
1233         User *user;
1234
1235         assert(m);
1236
1237         while ((seat = m->seat_gc_queue)) {
1238                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1239                 seat->in_gc_queue = false;
1240
1241                 if (seat_check_gc(seat, drop_not_started) == 0) {
1242                         seat_stop(seat);
1243                         seat_free(seat);
1244                 }
1245         }
1246
1247         while ((session = m->session_gc_queue)) {
1248                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1249                 session->in_gc_queue = false;
1250
1251                 if (session_check_gc(session, drop_not_started) == 0) {
1252                         session_stop(session);
1253                         session_finalize(session);
1254                         session_free(session);
1255                 }
1256         }
1257
1258         while ((user = m->user_gc_queue)) {
1259                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1260                 user->in_gc_queue = false;
1261
1262                 if (user_check_gc(user, drop_not_started) == 0) {
1263                         user_stop(user);
1264                         user_finalize(user);
1265                         user_free(user);
1266                 }
1267         }
1268 }
1269
1270 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1271         Session *s;
1272         bool idle_hint;
1273         dual_timestamp ts = { 0, 0 };
1274         Iterator i;
1275
1276         assert(m);
1277
1278         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1279
1280         HASHMAP_FOREACH(s, m->sessions, i) {
1281                 dual_timestamp k;
1282                 int ih;
1283
1284                 ih = session_get_idle_hint(s, &k);
1285                 if (ih < 0)
1286                         return ih;
1287
1288                 if (!ih) {
1289                         if (!idle_hint) {
1290                                 if (k.monotonic < ts.monotonic)
1291                                         ts = k;
1292                         } else {
1293                                 idle_hint = false;
1294                                 ts = k;
1295                         }
1296                 } else if (idle_hint) {
1297
1298                         if (k.monotonic > ts.monotonic)
1299                                 ts = k;
1300                 }
1301         }
1302
1303         if (t)
1304                 *t = ts;
1305
1306         return idle_hint;
1307 }
1308
1309 bool manager_shall_kill(Manager *m, const char *user) {
1310         assert(m);
1311         assert(user);
1312
1313         if (!m->kill_user_processes)
1314                 return false;
1315
1316         if (strv_contains(m->kill_exclude_users, user))
1317                 return false;
1318
1319         if (strv_isempty(m->kill_only_users))
1320                 return true;
1321
1322         return strv_contains(m->kill_only_users, user);
1323 }
1324
1325 int manager_dispatch_idle_action(Manager *m) {
1326         struct dual_timestamp since;
1327         struct itimerspec its = {};
1328         int r;
1329         usec_t n;
1330
1331         assert(m);
1332
1333         if (m->idle_action == HANDLE_IGNORE ||
1334             m->idle_action_usec <= 0) {
1335                 r = 0;
1336                 goto finish;
1337         }
1338
1339         n = now(CLOCK_MONOTONIC);
1340
1341         r = manager_get_idle_hint(m, &since);
1342         if (r <= 0)
1343                 /* Not idle. Let's check if after a timeout it might be idle then. */
1344                 timespec_store(&its.it_value, n + m->idle_action_usec);
1345         else {
1346                 /* Idle! Let's see if it's time to do something, or if
1347                  * we shall sleep for longer. */
1348
1349                 if (n >= since.monotonic + m->idle_action_usec &&
1350                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1351                         log_info("System idle. Taking action.");
1352
1353                         manager_handle_action(m, 0, m->idle_action, false, false);
1354                         m->idle_action_not_before_usec = n;
1355                 }
1356
1357                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1358         }
1359
1360         if (m->idle_action_fd < 0) {
1361                 struct epoll_event ev = {
1362                         .events = EPOLLIN,
1363                         .data.u32 = FD_IDLE_ACTION,
1364                 };
1365
1366                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1367                 if (m->idle_action_fd < 0) {
1368                         log_error("Failed to create idle action timer: %m");
1369                         r = -errno;
1370                         goto finish;
1371                 }
1372
1373                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1374                         log_error("Failed to add idle action timer to epoll: %m");
1375                         r = -errno;
1376                         goto finish;
1377                 }
1378         }
1379
1380         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1381                 log_error("Failed to reset timerfd: %m");
1382                 r = -errno;
1383                 goto finish;
1384         }
1385
1386         return 0;
1387
1388 finish:
1389         if (m->idle_action_fd >= 0) {
1390                 close_nointr_nofail(m->idle_action_fd);
1391                 m->idle_action_fd = -1;
1392         }
1393
1394         return r;
1395 }
1396 int manager_startup(Manager *m) {
1397         int r;
1398         Seat *seat;
1399         Session *session;
1400         User *user;
1401         Inhibitor *inhibitor;
1402         Iterator i;
1403
1404         assert(m);
1405         assert(m->epoll_fd <= 0);
1406
1407         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1408         if (m->epoll_fd < 0)
1409                 return -errno;
1410
1411         /* Connect to console */
1412         r = manager_connect_console(m);
1413         if (r < 0)
1414                 return r;
1415
1416         /* Connect to udev */
1417         r = manager_connect_udev(m);
1418         if (r < 0)
1419                 return r;
1420
1421         /* Connect to the bus */
1422         r = manager_connect_bus(m);
1423         if (r < 0)
1424                 return r;
1425
1426         /* Instantiate magic seat 0 */
1427         r = manager_add_seat(m, "seat0", &m->vtconsole);
1428         if (r < 0)
1429                 return r;
1430
1431         /* Deserialize state */
1432         r = manager_enumerate_devices(m);
1433         if (r < 0)
1434                 log_warning("Device enumeration failed: %s", strerror(-r));
1435
1436         r = manager_enumerate_seats(m);
1437         if (r < 0)
1438                 log_warning("Seat enumeration failed: %s", strerror(-r));
1439
1440         r = manager_enumerate_users(m);
1441         if (r < 0)
1442                 log_warning("User enumeration failed: %s", strerror(-r));
1443
1444         r = manager_enumerate_sessions(m);
1445         if (r < 0)
1446                 log_warning("Session enumeration failed: %s", strerror(-r));
1447
1448         r = manager_enumerate_inhibitors(m);
1449         if (r < 0)
1450                 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1451
1452         r = manager_enumerate_buttons(m);
1453         if (r < 0)
1454                 log_warning("Button enumeration failed: %s", strerror(-r));
1455
1456         /* Remove stale objects before we start them */
1457         manager_gc(m, false);
1458
1459         /* Reserve the special reserved VT */
1460         manager_reserve_vt(m);
1461
1462         /* And start everything */
1463         HASHMAP_FOREACH(seat, m->seats, i)
1464                 seat_start(seat);
1465
1466         HASHMAP_FOREACH(user, m->users, i)
1467                 user_start(user);
1468
1469         HASHMAP_FOREACH(session, m->sessions, i)
1470                 session_start(session);
1471
1472         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1473                 inhibitor_start(inhibitor);
1474
1475         manager_dispatch_idle_action(m);
1476
1477         return 0;
1478 }
1479
1480 static int manager_recheck_buttons(Manager *m) {
1481         Iterator i;
1482         Button *b;
1483         int r = 0;
1484
1485         assert(m);
1486
1487         HASHMAP_FOREACH(b, m->buttons, i) {
1488                 int q;
1489
1490                 q = button_recheck(b);
1491                 if (q > 0)
1492                         return 1;
1493                 if (q < 0)
1494                         r = q;
1495         }
1496
1497         return r;
1498 }
1499
1500 int manager_run(Manager *m) {
1501         assert(m);
1502
1503         for (;;) {
1504                 struct epoll_event event;
1505                 int n;
1506                 int msec = -1;
1507
1508                 manager_gc(m, true);
1509
1510                 if (manager_dispatch_delayed(m) > 0)
1511                         continue;
1512
1513                 if (manager_recheck_buttons(m) > 0)
1514                         continue;
1515
1516                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1517                         continue;
1518
1519                 manager_gc(m, true);
1520
1521                 if (m->action_what != 0 && !m->action_job) {
1522                         usec_t x, y;
1523
1524                         x = now(CLOCK_MONOTONIC);
1525                         y = m->action_timestamp + m->inhibit_delay_max;
1526
1527                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1528                 }
1529
1530                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1531                 if (n < 0) {
1532                         if (errno == EINTR || errno == EAGAIN)
1533                                 continue;
1534
1535                         log_error("epoll() failed: %m");
1536                         return -errno;
1537                 }
1538
1539                 if (n == 0)
1540                         continue;
1541
1542                 switch (event.data.u32) {
1543
1544                 case FD_SEAT_UDEV:
1545                         manager_dispatch_seat_udev(m);
1546                         break;
1547
1548                 case FD_VCSA_UDEV:
1549                         manager_dispatch_vcsa_udev(m);
1550                         break;
1551
1552                 case FD_BUTTON_UDEV:
1553                         manager_dispatch_button_udev(m);
1554                         break;
1555
1556                 case FD_CONSOLE:
1557                         manager_dispatch_console(m);
1558                         break;
1559
1560                 case FD_IDLE_ACTION:
1561                         manager_dispatch_idle_action(m);
1562                         break;
1563
1564                 case FD_BUS:
1565                         bus_loop_dispatch(m->bus_fd);
1566                         break;
1567
1568                 default:
1569                         if (event.data.u32 >= FD_OTHER_BASE)
1570                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1571                 }
1572         }
1573
1574         return 0;
1575 }
1576
1577 static int manager_parse_config_file(Manager *m) {
1578         static const char fn[] = "/etc/systemd/logind.conf";
1579         _cleanup_fclose_ FILE *f = NULL;
1580         int r;
1581
1582         assert(m);
1583
1584         f = fopen(fn, "re");
1585         if (!f) {
1586                 if (errno == ENOENT)
1587                         return 0;
1588
1589                 log_warning("Failed to open configuration file %s: %m", fn);
1590                 return -errno;
1591         }
1592
1593         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1594                          (void*) logind_gperf_lookup, false, false, m);
1595         if (r < 0)
1596                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1597
1598         return r;
1599 }
1600
1601 int main(int argc, char *argv[]) {
1602         Manager *m = NULL;
1603         int r;
1604
1605         log_set_target(LOG_TARGET_AUTO);
1606         log_set_facility(LOG_AUTH);
1607         log_parse_environment();
1608         log_open();
1609
1610         umask(0022);
1611
1612         if (argc != 1) {
1613                 log_error("This program takes no arguments.");
1614                 r = -EINVAL;
1615                 goto finish;
1616         }
1617
1618         /* Always create the directories people can create inotify
1619          * watches in. Note that some applications might check for the
1620          * existence of /run/systemd/seats/ to determine whether
1621          * logind is available, so please always make sure this check
1622          * stays in. */
1623         mkdir_label("/run/systemd/seats", 0755);
1624         mkdir_label("/run/systemd/users", 0755);
1625         mkdir_label("/run/systemd/sessions", 0755);
1626
1627         m = manager_new();
1628         if (!m) {
1629                 r = log_oom();
1630                 goto finish;
1631         }
1632
1633         manager_parse_config_file(m);
1634
1635         r = manager_startup(m);
1636         if (r < 0) {
1637                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1638                 goto finish;
1639         }
1640
1641         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1642
1643         sd_notify(false,
1644                   "READY=1\n"
1645                   "STATUS=Processing requests...");
1646
1647         r = manager_run(m);
1648
1649         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1650
1651 finish:
1652         sd_notify(false,
1653                   "STATUS=Shutting down...");
1654
1655         if (m)
1656                 manager_free(m);
1657
1658         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1659 }