LCOV - code coverage report
Current view: top level - login - logind-dbus.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 0 1910 0.0 %
Date: 2019-08-22 15:41:25 Functions: 0 106 0.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <errno.h>
       4             : #include <pwd.h>
       5             : #include <string.h>
       6             : #include <sys/stat.h>
       7             : #include <unistd.h>
       8             : 
       9             : #include "sd-device.h"
      10             : #include "sd-messages.h"
      11             : 
      12             : #include "alloc-util.h"
      13             : #include "audit-util.h"
      14             : #include "bootspec.h"
      15             : #include "bus-common-errors.h"
      16             : #include "bus-error.h"
      17             : #include "bus-unit-util.h"
      18             : #include "bus-util.h"
      19             : #include "cgroup-util.h"
      20             : #include "device-util.h"
      21             : #include "dirent-util.h"
      22             : #include "efivars.h"
      23             : #include "env-util.h"
      24             : #include "escape.h"
      25             : #include "fd-util.h"
      26             : #include "fileio-label.h"
      27             : #include "fileio.h"
      28             : #include "format-util.h"
      29             : #include "fs-util.h"
      30             : #include "logind-dbus.h"
      31             : #include "logind-seat-dbus.h"
      32             : #include "logind-session-dbus.h"
      33             : #include "logind-user-dbus.h"
      34             : #include "logind.h"
      35             : #include "missing_capability.h"
      36             : #include "mkdir.h"
      37             : #include "parse-util.h"
      38             : #include "path-util.h"
      39             : #include "process-util.h"
      40             : #include "reboot-util.h"
      41             : #include "selinux-util.h"
      42             : #include "sleep-config.h"
      43             : #include "special.h"
      44             : #include "stdio-util.h"
      45             : #include "strv.h"
      46             : #include "terminal-util.h"
      47             : #include "tmpfile-util.h"
      48             : #include "unit-name.h"
      49             : #include "user-util.h"
      50             : #include "utmp-wtmp.h"
      51             : #include "virt.h"
      52             : 
      53           0 : static int get_sender_session(
      54             :                 Manager *m,
      55             :                 sd_bus_message *message,
      56             :                 bool consult_display,
      57             :                 sd_bus_error *error,
      58             :                 Session **ret) {
      59             : 
      60           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
      61           0 :         Session *session = NULL;
      62             :         const char *name;
      63             :         int r;
      64             : 
      65             :         /* Acquire the sender's session. This first checks if the sending process is inside a session itself,
      66             :          * and returns that. If not and 'consult_display' is true, this returns the display session of the
      67             :          * owning user of the caller. */
      68             : 
      69           0 :         r = sd_bus_query_sender_creds(message,
      70             :                                       SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT|
      71             :                                       (consult_display ? SD_BUS_CREDS_OWNER_UID : 0), &creds);
      72           0 :         if (r < 0)
      73           0 :                 return r;
      74             : 
      75           0 :         r = sd_bus_creds_get_session(creds, &name);
      76           0 :         if (r < 0) {
      77           0 :                 if (r != -ENXIO)
      78           0 :                         return r;
      79             : 
      80           0 :                 if (consult_display) {
      81             :                         uid_t uid;
      82             : 
      83           0 :                         r = sd_bus_creds_get_owner_uid(creds, &uid);
      84           0 :                         if (r < 0) {
      85           0 :                                 if (r != -ENXIO)
      86           0 :                                         return r;
      87             :                         } else {
      88             :                                 User *user;
      89             : 
      90           0 :                                 user = hashmap_get(m->users, UID_TO_PTR(uid));
      91           0 :                                 if (user)
      92           0 :                                         session = user->display;
      93             :                         }
      94             :                 }
      95             :         } else
      96           0 :                 session = hashmap_get(m->sessions, name);
      97             : 
      98           0 :         if (!session)
      99           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
     100             :                                          consult_display ?
     101             :                                          "Caller does not belong to any known session and doesn't own any suitable session." :
     102             :                                          "Caller does not belong to any known session.");
     103             : 
     104           0 :         *ret = session;
     105           0 :         return 0;
     106             : }
     107             : 
     108           0 : int manager_get_session_from_creds(
     109             :                 Manager *m,
     110             :                 sd_bus_message *message,
     111             :                 const char *name,
     112             :                 sd_bus_error *error,
     113             :                 Session **ret) {
     114             : 
     115             :         Session *session;
     116             : 
     117           0 :         assert(m);
     118           0 :         assert(message);
     119           0 :         assert(ret);
     120             : 
     121           0 :         if (SEAT_IS_SELF(name)) /* the caller's own session */
     122           0 :                 return get_sender_session(m, message, false, error, ret);
     123           0 :         if (SEAT_IS_AUTO(name)) /* The caller's own session if they have one, otherwise their user's display session */
     124           0 :                 return get_sender_session(m, message, true, error, ret);
     125             : 
     126           0 :         session = hashmap_get(m->sessions, name);
     127           0 :         if (!session)
     128           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
     129             : 
     130           0 :         *ret = session;
     131           0 :         return 0;
     132             : }
     133             : 
     134           0 : static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *error, User **ret) {
     135           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
     136             :         uid_t uid;
     137             :         User *user;
     138             :         int r;
     139             : 
     140             :         /* Note that we get the owner UID of the session, not the actual client UID here! */
     141           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
     142           0 :         if (r < 0)
     143           0 :                 return r;
     144             : 
     145           0 :         r = sd_bus_creds_get_owner_uid(creds, &uid);
     146           0 :         if (r < 0) {
     147           0 :                 if (r != -ENXIO)
     148           0 :                         return r;
     149             : 
     150           0 :                 user = NULL;
     151             :         } else
     152           0 :                 user = hashmap_get(m->users, UID_TO_PTR(uid));
     153             : 
     154           0 :         if (!user)
     155           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID,
     156             :                                          "Caller does not belong to any logged in or lingering user");
     157             : 
     158           0 :         *ret = user;
     159           0 :         return 0;
     160             : }
     161             : 
     162           0 : int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
     163             :         User *user;
     164             : 
     165           0 :         assert(m);
     166           0 :         assert(message);
     167           0 :         assert(ret);
     168             : 
     169           0 :         if (!uid_is_valid(uid))
     170           0 :                 return get_sender_user(m, message, error, ret);
     171             : 
     172           0 :         user = hashmap_get(m->users, UID_TO_PTR(uid));
     173           0 :         if (!user)
     174           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER,
     175             :                                          "User ID "UID_FMT" is not logged in or lingering", uid);
     176             : 
     177           0 :         *ret = user;
     178           0 :         return 0;
     179             : }
     180             : 
     181           0 : int manager_get_seat_from_creds(
     182             :                 Manager *m,
     183             :                 sd_bus_message *message,
     184             :                 const char *name,
     185             :                 sd_bus_error *error,
     186             :                 Seat **ret) {
     187             : 
     188             :         Seat *seat;
     189             :         int r;
     190             : 
     191           0 :         assert(m);
     192           0 :         assert(message);
     193           0 :         assert(ret);
     194             : 
     195           0 :         if (SEAT_IS_SELF(name) || SEAT_IS_AUTO(name)) {
     196             :                 Session *session;
     197             : 
     198             :                 /* Use these special seat names as session names */
     199           0 :                 r = manager_get_session_from_creds(m, message, name, error, &session);
     200           0 :                 if (r < 0)
     201           0 :                         return r;
     202             : 
     203           0 :                 seat = session->seat;
     204           0 :                 if (!seat)
     205           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session '%s' has no seat.", session->id);
     206             :         } else {
     207           0 :                 seat = hashmap_get(m->seats, name);
     208           0 :                 if (!seat)
     209           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
     210             :         }
     211             : 
     212           0 :         *ret = seat;
     213           0 :         return 0;
     214             : }
     215             : 
     216           0 : static int return_test_polkit(
     217             :                 sd_bus_message *message,
     218             :                 int capability,
     219             :                 const char *action,
     220             :                 const char **details,
     221             :                 uid_t good_user,
     222             :                 sd_bus_error *e) {
     223             : 
     224             :         const char *result;
     225             :         bool challenge;
     226             :         int r;
     227             : 
     228           0 :         r = bus_test_polkit(message, capability, action, details, good_user, &challenge, e);
     229           0 :         if (r < 0)
     230           0 :                 return r;
     231             : 
     232           0 :         if (r > 0)
     233           0 :                 result = "yes";
     234           0 :         else if (challenge)
     235           0 :                 result = "challenge";
     236             :         else
     237           0 :                 result = "no";
     238             : 
     239           0 :         return sd_bus_reply_method_return(message, "s", result);
     240             : }
     241             : 
     242           0 : static int property_get_idle_hint(
     243             :                 sd_bus *bus,
     244             :                 const char *path,
     245             :                 const char *interface,
     246             :                 const char *property,
     247             :                 sd_bus_message *reply,
     248             :                 void *userdata,
     249             :                 sd_bus_error *error) {
     250             : 
     251           0 :         Manager *m = userdata;
     252             : 
     253           0 :         assert(bus);
     254           0 :         assert(reply);
     255           0 :         assert(m);
     256             : 
     257           0 :         return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
     258             : }
     259             : 
     260           0 : static int property_get_idle_since_hint(
     261             :                 sd_bus *bus,
     262             :                 const char *path,
     263             :                 const char *interface,
     264             :                 const char *property,
     265             :                 sd_bus_message *reply,
     266             :                 void *userdata,
     267             :                 sd_bus_error *error) {
     268             : 
     269           0 :         Manager *m = userdata;
     270           0 :         dual_timestamp t = DUAL_TIMESTAMP_NULL;
     271             : 
     272           0 :         assert(bus);
     273           0 :         assert(reply);
     274           0 :         assert(m);
     275             : 
     276           0 :         manager_get_idle_hint(m, &t);
     277             : 
     278           0 :         return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
     279             : }
     280             : 
     281           0 : static int property_get_inhibited(
     282             :                 sd_bus *bus,
     283             :                 const char *path,
     284             :                 const char *interface,
     285             :                 const char *property,
     286             :                 sd_bus_message *reply,
     287             :                 void *userdata,
     288             :                 sd_bus_error *error) {
     289             : 
     290           0 :         Manager *m = userdata;
     291             :         InhibitWhat w;
     292             : 
     293           0 :         assert(bus);
     294           0 :         assert(reply);
     295           0 :         assert(m);
     296             : 
     297           0 :         w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
     298             : 
     299           0 :         return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
     300             : }
     301             : 
     302           0 : static int property_get_preparing(
     303             :                 sd_bus *bus,
     304             :                 const char *path,
     305             :                 const char *interface,
     306             :                 const char *property,
     307             :                 sd_bus_message *reply,
     308             :                 void *userdata,
     309             :                 sd_bus_error *error) {
     310             : 
     311           0 :         Manager *m = userdata;
     312             :         bool b;
     313             : 
     314           0 :         assert(bus);
     315           0 :         assert(reply);
     316           0 :         assert(m);
     317             : 
     318           0 :         if (streq(property, "PreparingForShutdown"))
     319           0 :                 b = m->action_what & INHIBIT_SHUTDOWN;
     320             :         else
     321           0 :                 b = m->action_what & INHIBIT_SLEEP;
     322             : 
     323           0 :         return sd_bus_message_append(reply, "b", b);
     324             : }
     325             : 
     326           0 : static int property_get_scheduled_shutdown(
     327             :                 sd_bus *bus,
     328             :                 const char *path,
     329             :                 const char *interface,
     330             :                 const char *property,
     331             :                 sd_bus_message *reply,
     332             :                 void *userdata,
     333             :                 sd_bus_error *error) {
     334             : 
     335           0 :         Manager *m = userdata;
     336             :         int r;
     337             : 
     338           0 :         assert(bus);
     339           0 :         assert(reply);
     340           0 :         assert(m);
     341             : 
     342           0 :         r = sd_bus_message_open_container(reply, 'r', "st");
     343           0 :         if (r < 0)
     344           0 :                 return r;
     345             : 
     346           0 :         r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
     347           0 :         if (r < 0)
     348           0 :                 return r;
     349             : 
     350           0 :         return sd_bus_message_close_container(reply);
     351             : }
     352             : 
     353           0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
     354           0 : static BUS_DEFINE_PROPERTY_GET(property_get_docked, "b", Manager, manager_is_docked_or_external_displays);
     355           0 : static BUS_DEFINE_PROPERTY_GET(property_get_lid_closed, "b", Manager, manager_is_lid_closed);
     356           0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_on_external_power, "b", manager_is_on_external_power);
     357           0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_compat_user_tasks_max, "t", CGROUP_LIMIT_MAX);
     358           0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "t", Hashmap *, (uint64_t) hashmap_size);
     359             : 
     360           0 : static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     361           0 :         _cleanup_free_ char *p = NULL;
     362           0 :         Manager *m = userdata;
     363             :         const char *name;
     364             :         Session *session;
     365             :         int r;
     366             : 
     367           0 :         assert(message);
     368           0 :         assert(m);
     369             : 
     370           0 :         r = sd_bus_message_read(message, "s", &name);
     371           0 :         if (r < 0)
     372           0 :                 return r;
     373             : 
     374           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     375           0 :         if (r < 0)
     376           0 :                 return r;
     377             : 
     378           0 :         p = session_bus_path(session);
     379           0 :         if (!p)
     380           0 :                 return -ENOMEM;
     381             : 
     382           0 :         return sd_bus_reply_method_return(message, "o", p);
     383             : }
     384             : 
     385             : /* Get login session of a process.  This is not what you are looking for these days,
     386             :  * as apps may instead belong to a user service unit.  This includes terminal
     387             :  * emulators and hence command-line apps. */
     388           0 : static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     389           0 :         _cleanup_free_ char *p = NULL;
     390           0 :         Session *session = NULL;
     391           0 :         Manager *m = userdata;
     392             :         pid_t pid;
     393             :         int r;
     394             : 
     395           0 :         assert(message);
     396           0 :         assert(m);
     397             : 
     398             :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     399             : 
     400           0 :         r = sd_bus_message_read(message, "u", &pid);
     401           0 :         if (r < 0)
     402           0 :                 return r;
     403           0 :         if (pid < 0)
     404           0 :                 return -EINVAL;
     405             : 
     406           0 :         if (pid == 0) {
     407           0 :                 r = manager_get_session_from_creds(m, message, NULL, error, &session);
     408           0 :                 if (r < 0)
     409           0 :                         return r;
     410             :         } else {
     411           0 :                 r = manager_get_session_by_pid(m, pid, &session);
     412           0 :                 if (r < 0)
     413           0 :                         return r;
     414             : 
     415           0 :                 if (!session)
     416           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
     417             :                                                  "PID "PID_FMT" does not belong to any known session", pid);
     418             :         }
     419             : 
     420           0 :         p = session_bus_path(session);
     421           0 :         if (!p)
     422           0 :                 return -ENOMEM;
     423             : 
     424           0 :         return sd_bus_reply_method_return(message, "o", p);
     425             : }
     426             : 
     427           0 : static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     428           0 :         _cleanup_free_ char *p = NULL;
     429           0 :         Manager *m = userdata;
     430             :         uint32_t uid;
     431             :         User *user;
     432             :         int r;
     433             : 
     434           0 :         assert(message);
     435           0 :         assert(m);
     436             : 
     437           0 :         r = sd_bus_message_read(message, "u", &uid);
     438           0 :         if (r < 0)
     439           0 :                 return r;
     440             : 
     441           0 :         r = manager_get_user_from_creds(m, message, uid, error, &user);
     442           0 :         if (r < 0)
     443           0 :                 return r;
     444             : 
     445           0 :         p = user_bus_path(user);
     446           0 :         if (!p)
     447           0 :                 return -ENOMEM;
     448             : 
     449           0 :         return sd_bus_reply_method_return(message, "o", p);
     450             : }
     451             : 
     452           0 : static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     453           0 :         _cleanup_free_ char *p = NULL;
     454           0 :         Manager *m = userdata;
     455           0 :         User *user = NULL;
     456             :         pid_t pid;
     457             :         int r;
     458             : 
     459           0 :         assert(message);
     460           0 :         assert(m);
     461             : 
     462             :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     463             : 
     464           0 :         r = sd_bus_message_read(message, "u", &pid);
     465           0 :         if (r < 0)
     466           0 :                 return r;
     467           0 :         if (pid < 0)
     468           0 :                 return -EINVAL;
     469             : 
     470           0 :         if (pid == 0) {
     471           0 :                 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
     472           0 :                 if (r < 0)
     473           0 :                         return r;
     474             :         } else {
     475           0 :                 r = manager_get_user_by_pid(m, pid, &user);
     476           0 :                 if (r < 0)
     477           0 :                         return r;
     478           0 :                 if (!user)
     479           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID,
     480             :                                                  "PID "PID_FMT" does not belong to any logged in user or lingering user",
     481             :                                                  pid);
     482             :         }
     483             : 
     484           0 :         p = user_bus_path(user);
     485           0 :         if (!p)
     486           0 :                 return -ENOMEM;
     487             : 
     488           0 :         return sd_bus_reply_method_return(message, "o", p);
     489             : }
     490             : 
     491           0 : static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     492           0 :         _cleanup_free_ char *p = NULL;
     493           0 :         Manager *m = userdata;
     494             :         const char *name;
     495             :         Seat *seat;
     496             :         int r;
     497             : 
     498           0 :         assert(message);
     499           0 :         assert(m);
     500             : 
     501           0 :         r = sd_bus_message_read(message, "s", &name);
     502           0 :         if (r < 0)
     503           0 :                 return r;
     504             : 
     505           0 :         r = manager_get_seat_from_creds(m, message, name, error, &seat);
     506           0 :         if (r < 0)
     507           0 :                 return r;
     508             : 
     509           0 :         p = seat_bus_path(seat);
     510           0 :         if (!p)
     511           0 :                 return -ENOMEM;
     512             : 
     513           0 :         return sd_bus_reply_method_return(message, "o", p);
     514             : }
     515             : 
     516           0 : static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     517           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
     518           0 :         Manager *m = userdata;
     519             :         Session *session;
     520             :         Iterator i;
     521             :         int r;
     522             : 
     523           0 :         assert(message);
     524           0 :         assert(m);
     525             : 
     526           0 :         r = sd_bus_message_new_method_return(message, &reply);
     527           0 :         if (r < 0)
     528           0 :                 return r;
     529             : 
     530           0 :         r = sd_bus_message_open_container(reply, 'a', "(susso)");
     531           0 :         if (r < 0)
     532           0 :                 return r;
     533             : 
     534           0 :         HASHMAP_FOREACH(session, m->sessions, i) {
     535           0 :                 _cleanup_free_ char *p = NULL;
     536             : 
     537           0 :                 p = session_bus_path(session);
     538           0 :                 if (!p)
     539           0 :                         return -ENOMEM;
     540             : 
     541           0 :                 r = sd_bus_message_append(reply, "(susso)",
     542           0 :                                           session->id,
     543           0 :                                           (uint32_t) session->user->uid,
     544           0 :                                           session->user->name,
     545           0 :                                           session->seat ? session->seat->id : "",
     546             :                                           p);
     547           0 :                 if (r < 0)
     548           0 :                         return r;
     549             :         }
     550             : 
     551           0 :         r = sd_bus_message_close_container(reply);
     552           0 :         if (r < 0)
     553           0 :                 return r;
     554             : 
     555           0 :         return sd_bus_send(NULL, reply, NULL);
     556             : }
     557             : 
     558           0 : static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     559           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
     560           0 :         Manager *m = userdata;
     561             :         User *user;
     562             :         Iterator i;
     563             :         int r;
     564             : 
     565           0 :         assert(message);
     566           0 :         assert(m);
     567             : 
     568           0 :         r = sd_bus_message_new_method_return(message, &reply);
     569           0 :         if (r < 0)
     570           0 :                 return r;
     571             : 
     572           0 :         r = sd_bus_message_open_container(reply, 'a', "(uso)");
     573           0 :         if (r < 0)
     574           0 :                 return r;
     575             : 
     576           0 :         HASHMAP_FOREACH(user, m->users, i) {
     577           0 :                 _cleanup_free_ char *p = NULL;
     578             : 
     579           0 :                 p = user_bus_path(user);
     580           0 :                 if (!p)
     581           0 :                         return -ENOMEM;
     582             : 
     583           0 :                 r = sd_bus_message_append(reply, "(uso)",
     584           0 :                                           (uint32_t) user->uid,
     585           0 :                                           user->name,
     586             :                                           p);
     587           0 :                 if (r < 0)
     588           0 :                         return r;
     589             :         }
     590             : 
     591           0 :         r = sd_bus_message_close_container(reply);
     592           0 :         if (r < 0)
     593           0 :                 return r;
     594             : 
     595           0 :         return sd_bus_send(NULL, reply, NULL);
     596             : }
     597             : 
     598           0 : static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     599           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
     600           0 :         Manager *m = userdata;
     601             :         Seat *seat;
     602             :         Iterator i;
     603             :         int r;
     604             : 
     605           0 :         assert(message);
     606           0 :         assert(m);
     607             : 
     608           0 :         r = sd_bus_message_new_method_return(message, &reply);
     609           0 :         if (r < 0)
     610           0 :                 return r;
     611             : 
     612           0 :         r = sd_bus_message_open_container(reply, 'a', "(so)");
     613           0 :         if (r < 0)
     614           0 :                 return r;
     615             : 
     616           0 :         HASHMAP_FOREACH(seat, m->seats, i) {
     617           0 :                 _cleanup_free_ char *p = NULL;
     618             : 
     619           0 :                 p = seat_bus_path(seat);
     620           0 :                 if (!p)
     621           0 :                         return -ENOMEM;
     622             : 
     623           0 :                 r = sd_bus_message_append(reply, "(so)", seat->id, p);
     624           0 :                 if (r < 0)
     625           0 :                         return r;
     626             :         }
     627             : 
     628           0 :         r = sd_bus_message_close_container(reply);
     629           0 :         if (r < 0)
     630           0 :                 return r;
     631             : 
     632           0 :         return sd_bus_send(NULL, reply, NULL);
     633             : }
     634             : 
     635           0 : static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     636           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
     637           0 :         Manager *m = userdata;
     638             :         Inhibitor *inhibitor;
     639             :         Iterator i;
     640             :         int r;
     641             : 
     642           0 :         assert(message);
     643           0 :         assert(m);
     644             : 
     645           0 :         r = sd_bus_message_new_method_return(message, &reply);
     646           0 :         if (r < 0)
     647           0 :                 return r;
     648             : 
     649           0 :         r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
     650           0 :         if (r < 0)
     651           0 :                 return r;
     652             : 
     653           0 :         HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
     654             : 
     655           0 :                 r = sd_bus_message_append(reply, "(ssssuu)",
     656           0 :                                           strempty(inhibit_what_to_string(inhibitor->what)),
     657           0 :                                           strempty(inhibitor->who),
     658           0 :                                           strempty(inhibitor->why),
     659           0 :                                           strempty(inhibit_mode_to_string(inhibitor->mode)),
     660           0 :                                           (uint32_t) inhibitor->uid,
     661           0 :                                           (uint32_t) inhibitor->pid);
     662           0 :                 if (r < 0)
     663           0 :                         return r;
     664             :         }
     665             : 
     666           0 :         r = sd_bus_message_close_container(reply);
     667           0 :         if (r < 0)
     668           0 :                 return r;
     669             : 
     670           0 :         return sd_bus_send(NULL, reply, NULL);
     671             : }
     672             : 
     673           0 : static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     674             :         const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
     675           0 :         _cleanup_free_ char *id = NULL;
     676           0 :         Session *session = NULL;
     677           0 :         uint32_t audit_id = 0;
     678           0 :         Manager *m = userdata;
     679           0 :         User *user = NULL;
     680           0 :         Seat *seat = NULL;
     681             :         pid_t leader;
     682             :         uid_t uid;
     683             :         int remote;
     684           0 :         uint32_t vtnr = 0;
     685             :         SessionType t;
     686             :         SessionClass c;
     687             :         int r;
     688             : 
     689           0 :         assert(message);
     690           0 :         assert(m);
     691             : 
     692             :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     693             :         assert_cc(sizeof(uid_t) == sizeof(uint32_t));
     694             : 
     695           0 :         r = sd_bus_message_read(message, "uusssssussbss",
     696             :                                 &uid, &leader, &service, &type, &class, &desktop, &cseat,
     697             :                                 &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
     698           0 :         if (r < 0)
     699           0 :                 return r;
     700             : 
     701           0 :         if (!uid_is_valid(uid))
     702           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UID");
     703           0 :         if (leader < 0 || leader == 1 || leader == getpid_cached())
     704           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
     705             : 
     706           0 :         if (isempty(type))
     707           0 :                 t = _SESSION_TYPE_INVALID;
     708             :         else {
     709           0 :                 t = session_type_from_string(type);
     710           0 :                 if (t < 0)
     711           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     712             :                                                  "Invalid session type %s", type);
     713             :         }
     714             : 
     715           0 :         if (isempty(class))
     716           0 :                 c = _SESSION_CLASS_INVALID;
     717             :         else {
     718           0 :                 c = session_class_from_string(class);
     719           0 :                 if (c < 0)
     720           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     721             :                                                  "Invalid session class %s", class);
     722             :         }
     723             : 
     724           0 :         if (isempty(desktop))
     725           0 :                 desktop = NULL;
     726             :         else {
     727           0 :                 if (!string_is_safe(desktop))
     728           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     729             :                                                  "Invalid desktop string %s", desktop);
     730             :         }
     731             : 
     732           0 :         if (isempty(cseat))
     733           0 :                 seat = NULL;
     734             :         else {
     735           0 :                 seat = hashmap_get(m->seats, cseat);
     736           0 :                 if (!seat)
     737           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT,
     738             :                                                  "No seat '%s' known", cseat);
     739             :         }
     740             : 
     741           0 :         if (tty_is_vc(tty)) {
     742             :                 int v;
     743             : 
     744           0 :                 if (!seat)
     745           0 :                         seat = m->seat0;
     746           0 :                 else if (seat != m->seat0)
     747           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     748             :                                                  "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
     749             : 
     750           0 :                 v = vtnr_from_tty(tty);
     751           0 :                 if (v <= 0)
     752           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     753             :                                                  "Cannot determine VT number from virtual console TTY %s", tty);
     754             : 
     755           0 :                 if (vtnr == 0)
     756           0 :                         vtnr = (uint32_t) v;
     757           0 :                 else if (vtnr != (uint32_t) v)
     758           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     759             :                                                  "Specified TTY and VT number do not match");
     760             : 
     761           0 :         } else if (tty_is_console(tty)) {
     762             : 
     763           0 :                 if (!seat)
     764           0 :                         seat = m->seat0;
     765           0 :                 else if (seat != m->seat0)
     766           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     767             :                                                  "Console TTY specified but seat is not seat0");
     768             : 
     769           0 :                 if (vtnr != 0)
     770           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     771             :                                                  "Console TTY specified but VT number is not 0");
     772             :         }
     773             : 
     774           0 :         if (seat) {
     775           0 :                 if (seat_has_vts(seat)) {
     776           0 :                         if (vtnr <= 0 || vtnr > 63)
     777           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     778             :                                                          "VT number out of range");
     779             :                 } else {
     780           0 :                         if (vtnr != 0)
     781           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     782             :                                                          "Seat has no VTs but VT number not 0");
     783             :                 }
     784             :         }
     785             : 
     786           0 :         if (t == _SESSION_TYPE_INVALID) {
     787           0 :                 if (!isempty(display))
     788           0 :                         t = SESSION_X11;
     789           0 :                 else if (!isempty(tty))
     790           0 :                         t = SESSION_TTY;
     791             :                 else
     792           0 :                         t = SESSION_UNSPECIFIED;
     793             :         }
     794             : 
     795           0 :         if (c == _SESSION_CLASS_INVALID) {
     796           0 :                 if (t == SESSION_UNSPECIFIED)
     797           0 :                         c = SESSION_BACKGROUND;
     798             :                 else
     799           0 :                         c = SESSION_USER;
     800             :         }
     801             : 
     802           0 :         if (leader == 0) {
     803           0 :                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
     804             : 
     805           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     806           0 :                 if (r < 0)
     807           0 :                         return r;
     808             : 
     809           0 :                 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
     810           0 :                 if (r < 0)
     811           0 :                         return r;
     812             :         }
     813             : 
     814             :         /* Check if we are already in a logind session. Or if we are in user@.service
     815             :          * which is a special PAM session that avoids creating a logind session. */
     816           0 :         r = manager_get_user_by_pid(m, leader, NULL);
     817           0 :         if (r < 0)
     818           0 :                 return r;
     819           0 :         if (r > 0)
     820           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY,
     821             :                                          "Already running in a session or user slice");
     822             : 
     823             :         /*
     824             :          * Old gdm and lightdm start the user-session on the same VT as
     825             :          * the greeter session. But they destroy the greeter session
     826             :          * after the user-session and want the user-session to take
     827             :          * over the VT. We need to support this for
     828             :          * backwards-compatibility, so make sure we allow new sessions
     829             :          * on a VT that a greeter is running on. Furthermore, to allow
     830             :          * re-logins, we have to allow a greeter to take over a used VT for
     831             :          * the exact same reasons.
     832             :          */
     833           0 :         if (c != SESSION_GREETER &&
     834           0 :             vtnr > 0 &&
     835           0 :             vtnr < m->seat0->position_count &&
     836           0 :             m->seat0->positions[vtnr] &&
     837           0 :             m->seat0->positions[vtnr]->class != SESSION_GREETER)
     838           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
     839             : 
     840           0 :         if (hashmap_size(m->sessions) >= m->sessions_max)
     841           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED,
     842             :                                          "Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.",
     843             :                                          m->sessions_max);
     844             : 
     845           0 :         (void) audit_session_from_pid(leader, &audit_id);
     846           0 :         if (audit_session_is_valid(audit_id)) {
     847             :                 /* Keep our session IDs and the audit session IDs in sync */
     848             : 
     849           0 :                 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
     850           0 :                         return -ENOMEM;
     851             : 
     852             :                 /* Wut? There's already a session by this name and we didn't find it above? Weird, then let's
     853             :                  * not trust the audit data and let's better register a new ID */
     854           0 :                 if (hashmap_contains(m->sessions, id)) {
     855           0 :                         log_warning("Existing logind session ID %s used by new audit session, ignoring.", id);
     856           0 :                         audit_id = AUDIT_SESSION_INVALID;
     857           0 :                         id = mfree(id);
     858             :                 }
     859             :         }
     860             : 
     861           0 :         if (!id) {
     862             :                 do {
     863           0 :                         id = mfree(id);
     864             : 
     865           0 :                         if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
     866           0 :                                 return -ENOMEM;
     867             : 
     868           0 :                 } while (hashmap_contains(m->sessions, id));
     869             :         }
     870             : 
     871             :         /* The generated names should not clash with 'auto' or 'self' */
     872           0 :         assert(!SESSION_IS_SELF(id));
     873           0 :         assert(!SESSION_IS_AUTO(id));
     874             : 
     875             :         /* If we are not watching utmp already, try again */
     876           0 :         manager_reconnect_utmp(m);
     877             : 
     878           0 :         r = manager_add_user_by_uid(m, uid, &user);
     879           0 :         if (r < 0)
     880           0 :                 goto fail;
     881             : 
     882           0 :         r = manager_add_session(m, id, &session);
     883           0 :         if (r < 0)
     884           0 :                 goto fail;
     885             : 
     886           0 :         session_set_user(session, user);
     887           0 :         r = session_set_leader(session, leader);
     888           0 :         if (r < 0)
     889           0 :                 goto fail;
     890             : 
     891           0 :         session->type = t;
     892           0 :         session->class = c;
     893           0 :         session->remote = remote;
     894           0 :         session->vtnr = vtnr;
     895             : 
     896           0 :         if (!isempty(tty)) {
     897           0 :                 session->tty = strdup(tty);
     898           0 :                 if (!session->tty) {
     899           0 :                         r = -ENOMEM;
     900           0 :                         goto fail;
     901             :                 }
     902             : 
     903           0 :                 session->tty_validity = TTY_FROM_PAM;
     904             :         }
     905             : 
     906           0 :         if (!isempty(display)) {
     907           0 :                 session->display = strdup(display);
     908           0 :                 if (!session->display) {
     909           0 :                         r = -ENOMEM;
     910           0 :                         goto fail;
     911             :                 }
     912             :         }
     913             : 
     914           0 :         if (!isempty(remote_user)) {
     915           0 :                 session->remote_user = strdup(remote_user);
     916           0 :                 if (!session->remote_user) {
     917           0 :                         r = -ENOMEM;
     918           0 :                         goto fail;
     919             :                 }
     920             :         }
     921             : 
     922           0 :         if (!isempty(remote_host)) {
     923           0 :                 session->remote_host = strdup(remote_host);
     924           0 :                 if (!session->remote_host) {
     925           0 :                         r = -ENOMEM;
     926           0 :                         goto fail;
     927             :                 }
     928             :         }
     929             : 
     930           0 :         if (!isempty(service)) {
     931           0 :                 session->service = strdup(service);
     932           0 :                 if (!session->service) {
     933           0 :                         r = -ENOMEM;
     934           0 :                         goto fail;
     935             :                 }
     936             :         }
     937             : 
     938           0 :         if (!isempty(desktop)) {
     939           0 :                 session->desktop = strdup(desktop);
     940           0 :                 if (!session->desktop) {
     941           0 :                         r = -ENOMEM;
     942           0 :                         goto fail;
     943             :                 }
     944             :         }
     945             : 
     946           0 :         if (seat) {
     947           0 :                 r = seat_attach_session(seat, session);
     948           0 :                 if (r < 0)
     949           0 :                         goto fail;
     950             :         }
     951             : 
     952           0 :         r = sd_bus_message_enter_container(message, 'a', "(sv)");
     953           0 :         if (r < 0)
     954           0 :                 goto fail;
     955             : 
     956           0 :         r = session_start(session, message, error);
     957           0 :         if (r < 0)
     958           0 :                 goto fail;
     959             : 
     960           0 :         r = sd_bus_message_exit_container(message);
     961           0 :         if (r < 0)
     962           0 :                 goto fail;
     963             : 
     964           0 :         session->create_message = sd_bus_message_ref(message);
     965             : 
     966             :         /* Now, let's wait until the slice unit and stuff got created. We send the reply back from
     967             :          * session_send_create_reply(). */
     968             : 
     969           0 :         return 1;
     970             : 
     971           0 : fail:
     972           0 :         if (session)
     973           0 :                 session_add_to_gc_queue(session);
     974             : 
     975           0 :         if (user)
     976           0 :                 user_add_to_gc_queue(user);
     977             : 
     978           0 :         return r;
     979             : }
     980             : 
     981           0 : static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     982           0 :         Manager *m = userdata;
     983             :         Session *session;
     984             :         const char *name;
     985             :         int r;
     986             : 
     987           0 :         assert(message);
     988           0 :         assert(m);
     989             : 
     990           0 :         r = sd_bus_message_read(message, "s", &name);
     991           0 :         if (r < 0)
     992           0 :                 return r;
     993             : 
     994           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     995           0 :         if (r < 0)
     996           0 :                 return r;
     997             : 
     998           0 :         r = session_release(session);
     999           0 :         if (r < 0)
    1000           0 :                 return r;
    1001             : 
    1002           0 :         return sd_bus_reply_method_return(message, NULL);
    1003             : }
    1004             : 
    1005           0 : static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1006           0 :         Manager *m = userdata;
    1007             :         Session *session;
    1008             :         const char *name;
    1009             :         int r;
    1010             : 
    1011           0 :         assert(message);
    1012           0 :         assert(m);
    1013             : 
    1014           0 :         r = sd_bus_message_read(message, "s", &name);
    1015           0 :         if (r < 0)
    1016           0 :                 return r;
    1017             : 
    1018           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
    1019           0 :         if (r < 0)
    1020           0 :                 return r;
    1021             : 
    1022           0 :         return bus_session_method_activate(message, session, error);
    1023             : }
    1024             : 
    1025           0 : static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1026             :         const char *session_name, *seat_name;
    1027           0 :         Manager *m = userdata;
    1028             :         Session *session;
    1029             :         Seat *seat;
    1030             :         int r;
    1031             : 
    1032           0 :         assert(message);
    1033           0 :         assert(m);
    1034             : 
    1035             :         /* Same as ActivateSession() but refuses to work if the seat doesn't match */
    1036             : 
    1037           0 :         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
    1038           0 :         if (r < 0)
    1039           0 :                 return r;
    1040             : 
    1041           0 :         r = manager_get_session_from_creds(m, message, session_name, error, &session);
    1042           0 :         if (r < 0)
    1043           0 :                 return r;
    1044             : 
    1045           0 :         r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
    1046           0 :         if (r < 0)
    1047           0 :                 return r;
    1048             : 
    1049           0 :         if (session->seat != seat)
    1050           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT,
    1051             :                                          "Session %s not on seat %s", session_name, seat_name);
    1052             : 
    1053           0 :         r = session_activate(session);
    1054           0 :         if (r < 0)
    1055           0 :                 return r;
    1056             : 
    1057           0 :         return sd_bus_reply_method_return(message, NULL);
    1058             : }
    1059             : 
    1060           0 : static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1061           0 :         Manager *m = userdata;
    1062             :         Session *session;
    1063             :         const char *name;
    1064             :         int r;
    1065             : 
    1066           0 :         assert(message);
    1067           0 :         assert(m);
    1068             : 
    1069           0 :         r = sd_bus_message_read(message, "s", &name);
    1070           0 :         if (r < 0)
    1071           0 :                 return r;
    1072             : 
    1073           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
    1074           0 :         if (r < 0)
    1075           0 :                 return r;
    1076             : 
    1077           0 :         return bus_session_method_lock(message, session, error);
    1078             : }
    1079             : 
    1080           0 : static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1081           0 :         Manager *m = userdata;
    1082             :         int r;
    1083             : 
    1084           0 :         assert(message);
    1085           0 :         assert(m);
    1086             : 
    1087           0 :         r = bus_verify_polkit_async(
    1088             :                         message,
    1089             :                         CAP_SYS_ADMIN,
    1090             :                         "org.freedesktop.login1.lock-sessions",
    1091             :                         NULL,
    1092             :                         false,
    1093             :                         UID_INVALID,
    1094             :                         &m->polkit_registry,
    1095             :                         error);
    1096           0 :         if (r < 0)
    1097           0 :                 return r;
    1098           0 :         if (r == 0)
    1099           0 :                 return 1; /* Will call us back */
    1100             : 
    1101           0 :         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
    1102           0 :         if (r < 0)
    1103           0 :                 return r;
    1104             : 
    1105           0 :         return sd_bus_reply_method_return(message, NULL);
    1106             : }
    1107             : 
    1108           0 : static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1109             :         const char *name;
    1110           0 :         Manager *m = userdata;
    1111             :         Session *session;
    1112             :         int r;
    1113             : 
    1114           0 :         assert(message);
    1115           0 :         assert(m);
    1116             : 
    1117           0 :         r = sd_bus_message_read(message, "s", &name);
    1118           0 :         if (r < 0)
    1119           0 :                 return r;
    1120             : 
    1121           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
    1122           0 :         if (r < 0)
    1123           0 :                 return r;
    1124             : 
    1125           0 :         return bus_session_method_kill(message, session, error);
    1126             : }
    1127             : 
    1128           0 : static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1129           0 :         Manager *m = userdata;
    1130             :         uint32_t uid;
    1131             :         User *user;
    1132             :         int r;
    1133             : 
    1134           0 :         assert(message);
    1135           0 :         assert(m);
    1136             : 
    1137           0 :         r = sd_bus_message_read(message, "u", &uid);
    1138           0 :         if (r < 0)
    1139           0 :                 return r;
    1140             : 
    1141           0 :         r = manager_get_user_from_creds(m, message, uid, error, &user);
    1142           0 :         if (r < 0)
    1143           0 :                 return r;
    1144             : 
    1145           0 :         return bus_user_method_kill(message, user, error);
    1146             : }
    1147             : 
    1148           0 : static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1149           0 :         Manager *m = userdata;
    1150             :         const char *name;
    1151             :         Session *session;
    1152             :         int r;
    1153             : 
    1154           0 :         assert(message);
    1155           0 :         assert(m);
    1156             : 
    1157           0 :         r = sd_bus_message_read(message, "s", &name);
    1158           0 :         if (r < 0)
    1159           0 :                 return r;
    1160             : 
    1161           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
    1162           0 :         if (r < 0)
    1163           0 :                 return r;
    1164             : 
    1165           0 :         return bus_session_method_terminate(message, session, error);
    1166             : }
    1167             : 
    1168           0 : static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1169           0 :         Manager *m = userdata;
    1170             :         uint32_t uid;
    1171             :         User *user;
    1172             :         int r;
    1173             : 
    1174           0 :         assert(message);
    1175           0 :         assert(m);
    1176             : 
    1177           0 :         r = sd_bus_message_read(message, "u", &uid);
    1178           0 :         if (r < 0)
    1179           0 :                 return r;
    1180             : 
    1181           0 :         r = manager_get_user_from_creds(m, message, uid, error, &user);
    1182           0 :         if (r < 0)
    1183           0 :                 return r;
    1184             : 
    1185           0 :         return bus_user_method_terminate(message, user, error);
    1186             : }
    1187             : 
    1188           0 : static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1189           0 :         Manager *m = userdata;
    1190             :         const char *name;
    1191             :         Seat *seat;
    1192             :         int r;
    1193             : 
    1194           0 :         assert(message);
    1195           0 :         assert(m);
    1196             : 
    1197           0 :         r = sd_bus_message_read(message, "s", &name);
    1198           0 :         if (r < 0)
    1199           0 :                 return r;
    1200             : 
    1201           0 :         r = manager_get_seat_from_creds(m, message, name, error, &seat);
    1202           0 :         if (r < 0)
    1203           0 :                 return r;
    1204             : 
    1205           0 :         return bus_seat_method_terminate(message, seat, error);
    1206             : }
    1207             : 
    1208           0 : static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1209           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
    1210           0 :         _cleanup_free_ char *cc = NULL;
    1211           0 :         Manager *m = userdata;
    1212             :         int r, b, interactive;
    1213             :         struct passwd *pw;
    1214             :         const char *path;
    1215             :         uint32_t uid, auth_uid;
    1216             : 
    1217           0 :         assert(message);
    1218           0 :         assert(m);
    1219             : 
    1220           0 :         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
    1221           0 :         if (r < 0)
    1222           0 :                 return r;
    1223             : 
    1224           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID |
    1225             :                                                SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
    1226           0 :         if (r < 0)
    1227           0 :                 return r;
    1228             : 
    1229           0 :         if (!uid_is_valid(uid)) {
    1230             :                 /* Note that we get the owner UID of the session or user unit,
    1231             :                  * not the actual client UID here! */
    1232           0 :                 r = sd_bus_creds_get_owner_uid(creds, &uid);
    1233           0 :                 if (r < 0)
    1234           0 :                         return r;
    1235             :         }
    1236             : 
    1237             :         /* owner_uid is racy, so for authorization we must use euid */
    1238           0 :         r = sd_bus_creds_get_euid(creds, &auth_uid);
    1239           0 :         if (r < 0)
    1240           0 :                 return r;
    1241             : 
    1242           0 :         errno = 0;
    1243           0 :         pw = getpwuid(uid);
    1244           0 :         if (!pw)
    1245           0 :                 return errno_or_else(ENOENT);
    1246             : 
    1247           0 :         r = bus_verify_polkit_async(
    1248             :                         message,
    1249             :                         CAP_SYS_ADMIN,
    1250           0 :                         uid == auth_uid ? "org.freedesktop.login1.set-self-linger" :
    1251             :                                           "org.freedesktop.login1.set-user-linger",
    1252             :                         NULL,
    1253             :                         interactive,
    1254             :                         UID_INVALID,
    1255             :                         &m->polkit_registry,
    1256             :                         error);
    1257           0 :         if (r < 0)
    1258           0 :                 return r;
    1259           0 :         if (r == 0)
    1260           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1261             : 
    1262           0 :         (void) mkdir_p_label("/var/lib/systemd", 0755);
    1263           0 :         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0, MKDIR_WARN_MODE);
    1264           0 :         if (r < 0)
    1265           0 :                 return r;
    1266             : 
    1267           0 :         cc = cescape(pw->pw_name);
    1268           0 :         if (!cc)
    1269           0 :                 return -ENOMEM;
    1270             : 
    1271           0 :         path = strjoina("/var/lib/systemd/linger/", cc);
    1272           0 :         if (b) {
    1273             :                 User *u;
    1274             : 
    1275           0 :                 r = touch(path);
    1276           0 :                 if (r < 0)
    1277           0 :                         return r;
    1278             : 
    1279           0 :                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
    1280           0 :                         user_start(u);
    1281             : 
    1282             :         } else {
    1283             :                 User *u;
    1284             : 
    1285           0 :                 r = unlink(path);
    1286           0 :                 if (r < 0 && errno != ENOENT)
    1287           0 :                         return -errno;
    1288             : 
    1289           0 :                 u = hashmap_get(m->users, UID_TO_PTR(uid));
    1290           0 :                 if (u)
    1291           0 :                         user_add_to_gc_queue(u);
    1292             :         }
    1293             : 
    1294           0 :         return sd_bus_reply_method_return(message, NULL);
    1295             : }
    1296             : 
    1297           0 : static int trigger_device(Manager *m, sd_device *d) {
    1298           0 :         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
    1299             :         int r;
    1300             : 
    1301           0 :         assert(m);
    1302             : 
    1303           0 :         r = sd_device_enumerator_new(&e);
    1304           0 :         if (r < 0)
    1305           0 :                 return r;
    1306             : 
    1307           0 :         r = sd_device_enumerator_allow_uninitialized(e);
    1308           0 :         if (r < 0)
    1309           0 :                 return r;
    1310             : 
    1311           0 :         if (d) {
    1312           0 :                 r = sd_device_enumerator_add_match_parent(e, d);
    1313           0 :                 if (r < 0)
    1314           0 :                         return r;
    1315             :         }
    1316             : 
    1317           0 :         FOREACH_DEVICE(e, d) {
    1318           0 :                 _cleanup_free_ char *t = NULL;
    1319             :                 const char *p;
    1320             : 
    1321           0 :                 r = sd_device_get_syspath(d, &p);
    1322           0 :                 if (r < 0)
    1323           0 :                         return r;
    1324             : 
    1325           0 :                 t = path_join(p, "uevent");
    1326           0 :                 if (!t)
    1327           0 :                         return -ENOMEM;
    1328             : 
    1329           0 :                 (void) write_string_file(t, "change", WRITE_STRING_FILE_DISABLE_BUFFER);
    1330             :         }
    1331             : 
    1332           0 :         return 0;
    1333             : }
    1334             : 
    1335           0 : static int attach_device(Manager *m, const char *seat, const char *sysfs) {
    1336           0 :         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
    1337           0 :         _cleanup_free_ char *rule = NULL, *file = NULL;
    1338             :         const char *id_for_seat;
    1339             :         int r;
    1340             : 
    1341           0 :         assert(m);
    1342           0 :         assert(seat);
    1343           0 :         assert(sysfs);
    1344             : 
    1345           0 :         r = sd_device_new_from_syspath(&d, sysfs);
    1346           0 :         if (r < 0)
    1347           0 :                 return r;
    1348             : 
    1349           0 :         if (sd_device_has_tag(d, "seat") <= 0)
    1350           0 :                 return -ENODEV;
    1351             : 
    1352           0 :         if (sd_device_get_property_value(d, "ID_FOR_SEAT", &id_for_seat) < 0)
    1353           0 :                 return -ENODEV;
    1354             : 
    1355           0 :         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
    1356           0 :                 return -ENOMEM;
    1357             : 
    1358           0 :         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
    1359           0 :                 return -ENOMEM;
    1360             : 
    1361           0 :         (void) mkdir_p_label("/etc/udev/rules.d", 0755);
    1362           0 :         r = write_string_file_atomic_label(file, rule);
    1363           0 :         if (r < 0)
    1364           0 :                 return r;
    1365             : 
    1366           0 :         return trigger_device(m, d);
    1367             : }
    1368             : 
    1369           0 : static int flush_devices(Manager *m) {
    1370           0 :         _cleanup_closedir_ DIR *d;
    1371             : 
    1372           0 :         assert(m);
    1373             : 
    1374           0 :         d = opendir("/etc/udev/rules.d");
    1375           0 :         if (!d) {
    1376           0 :                 if (errno != ENOENT)
    1377           0 :                         log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
    1378             :         } else {
    1379             :                 struct dirent *de;
    1380             : 
    1381           0 :                 FOREACH_DIRENT_ALL(de, d, break) {
    1382           0 :                         if (!dirent_is_file(de))
    1383           0 :                                 continue;
    1384             : 
    1385           0 :                         if (!startswith(de->d_name, "72-seat-"))
    1386           0 :                                 continue;
    1387             : 
    1388           0 :                         if (!endswith(de->d_name, ".rules"))
    1389           0 :                                 continue;
    1390             : 
    1391           0 :                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
    1392           0 :                                 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
    1393             :                 }
    1394             :         }
    1395             : 
    1396           0 :         return trigger_device(m, NULL);
    1397             : }
    1398             : 
    1399           0 : static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1400             :         const char *sysfs, *seat;
    1401           0 :         Manager *m = userdata;
    1402             :         int interactive, r;
    1403             : 
    1404           0 :         assert(message);
    1405           0 :         assert(m);
    1406             : 
    1407           0 :         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
    1408           0 :         if (r < 0)
    1409           0 :                 return r;
    1410             : 
    1411           0 :         if (!path_is_normalized(sysfs))
    1412           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", sysfs);
    1413           0 :         if (!path_startswith(sysfs, "/sys"))
    1414           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
    1415             : 
    1416           0 :         if (SEAT_IS_SELF(seat) || SEAT_IS_AUTO(seat)) {
    1417             :                 Seat *found;
    1418             : 
    1419           0 :                 r = manager_get_seat_from_creds(m, message, seat, error, &found);
    1420           0 :                 if (r < 0)
    1421           0 :                         return r;
    1422             : 
    1423           0 :                 seat = found->id;
    1424             : 
    1425           0 :         } else if (!seat_name_is_valid(seat)) /* Note that a seat does not have to exist yet for this operation to succeed */
    1426           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat name %s is not valid", seat);
    1427             : 
    1428           0 :         r = bus_verify_polkit_async(
    1429             :                         message,
    1430             :                         CAP_SYS_ADMIN,
    1431             :                         "org.freedesktop.login1.attach-device",
    1432             :                         NULL,
    1433             :                         interactive,
    1434             :                         UID_INVALID,
    1435             :                         &m->polkit_registry,
    1436             :                         error);
    1437           0 :         if (r < 0)
    1438           0 :                 return r;
    1439           0 :         if (r == 0)
    1440           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1441             : 
    1442           0 :         r = attach_device(m, seat, sysfs);
    1443           0 :         if (r < 0)
    1444           0 :                 return r;
    1445             : 
    1446           0 :         return sd_bus_reply_method_return(message, NULL);
    1447             : }
    1448             : 
    1449           0 : static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1450           0 :         Manager *m = userdata;
    1451             :         int interactive, r;
    1452             : 
    1453           0 :         assert(message);
    1454           0 :         assert(m);
    1455             : 
    1456           0 :         r = sd_bus_message_read(message, "b", &interactive);
    1457           0 :         if (r < 0)
    1458           0 :                 return r;
    1459             : 
    1460           0 :         r = bus_verify_polkit_async(
    1461             :                         message,
    1462             :                         CAP_SYS_ADMIN,
    1463             :                         "org.freedesktop.login1.flush-devices",
    1464             :                         NULL,
    1465             :                         interactive,
    1466             :                         UID_INVALID,
    1467             :                         &m->polkit_registry,
    1468             :                         error);
    1469           0 :         if (r < 0)
    1470           0 :                 return r;
    1471           0 :         if (r == 0)
    1472           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1473             : 
    1474           0 :         r = flush_devices(m);
    1475           0 :         if (r < 0)
    1476           0 :                 return r;
    1477             : 
    1478           0 :         return sd_bus_reply_method_return(message, NULL);
    1479             : }
    1480             : 
    1481           0 : static int have_multiple_sessions(
    1482             :                 Manager *m,
    1483             :                 uid_t uid) {
    1484             : 
    1485             :         Session *session;
    1486             :         Iterator i;
    1487             : 
    1488           0 :         assert(m);
    1489             : 
    1490             :         /* Check for other users' sessions. Greeter sessions do not
    1491             :          * count, and non-login sessions do not count either. */
    1492           0 :         HASHMAP_FOREACH(session, m->sessions, i)
    1493           0 :                 if (session->class == SESSION_USER &&
    1494           0 :                     session->user->uid != uid)
    1495           0 :                         return true;
    1496             : 
    1497           0 :         return false;
    1498             : }
    1499             : 
    1500           0 : static int bus_manager_log_shutdown(
    1501             :                 Manager *m,
    1502             :                 const char *unit_name) {
    1503             : 
    1504             :         const char *p, *q;
    1505             : 
    1506           0 :         assert(m);
    1507           0 :         assert(unit_name);
    1508             : 
    1509           0 :         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
    1510           0 :                 p = "MESSAGE=System is powering down";
    1511           0 :                 q = "SHUTDOWN=power-off";
    1512           0 :         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
    1513           0 :                 p = "MESSAGE=System is rebooting";
    1514           0 :                 q = "SHUTDOWN=reboot";
    1515           0 :         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
    1516           0 :                 p = "MESSAGE=System is halting";
    1517           0 :                 q = "SHUTDOWN=halt";
    1518           0 :         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
    1519           0 :                 p = "MESSAGE=System is rebooting with kexec";
    1520           0 :                 q = "SHUTDOWN=kexec";
    1521             :         } else {
    1522           0 :                 p = "MESSAGE=System is shutting down";
    1523           0 :                 q = NULL;
    1524             :         }
    1525             : 
    1526           0 :         if (isempty(m->wall_message))
    1527           0 :                 p = strjoina(p, ".");
    1528             :         else
    1529           0 :                 p = strjoina(p, " (", m->wall_message, ").");
    1530             : 
    1531           0 :         return log_struct(LOG_NOTICE,
    1532             :                           "MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_STR,
    1533             :                           p,
    1534             :                           q);
    1535             : }
    1536             : 
    1537           0 : static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
    1538           0 :         Manager *m = userdata;
    1539             : 
    1540           0 :         assert(e);
    1541           0 :         assert(m);
    1542             : 
    1543           0 :         m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
    1544           0 :         return 0;
    1545             : }
    1546             : 
    1547           0 : int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
    1548             :         int r;
    1549             : 
    1550           0 :         assert(m);
    1551             : 
    1552           0 :         if (until <= now(CLOCK_MONOTONIC))
    1553           0 :                 return 0;
    1554             : 
    1555             :         /* We want to ignore the lid switch for a while after each
    1556             :          * suspend, and after boot-up. Hence let's install a timer for
    1557             :          * this. As long as the event source exists we ignore the lid
    1558             :          * switch. */
    1559             : 
    1560           0 :         if (m->lid_switch_ignore_event_source) {
    1561             :                 usec_t u;
    1562             : 
    1563           0 :                 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
    1564           0 :                 if (r < 0)
    1565           0 :                         return r;
    1566             : 
    1567           0 :                 if (until <= u)
    1568           0 :                         return 0;
    1569             : 
    1570           0 :                 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
    1571             :         } else
    1572           0 :                 r = sd_event_add_time(
    1573             :                                 m->event,
    1574             :                                 &m->lid_switch_ignore_event_source,
    1575             :                                 CLOCK_MONOTONIC,
    1576             :                                 until, 0,
    1577             :                                 lid_switch_ignore_handler, m);
    1578             : 
    1579           0 :         return r;
    1580             : }
    1581             : 
    1582           0 : static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
    1583           0 :         int active = _active;
    1584             : 
    1585           0 :         assert(m);
    1586           0 :         assert(IN_SET(w, INHIBIT_SHUTDOWN, INHIBIT_SLEEP));
    1587             : 
    1588           0 :         return sd_bus_emit_signal(m->bus,
    1589             :                                   "/org/freedesktop/login1",
    1590             :                                   "org.freedesktop.login1.Manager",
    1591             :                                   w == INHIBIT_SHUTDOWN ? "PrepareForShutdown" : "PrepareForSleep",
    1592             :                                   "b",
    1593             :                                   active);
    1594             : }
    1595             : 
    1596           0 : static int execute_shutdown_or_sleep(
    1597             :                 Manager *m,
    1598             :                 InhibitWhat w,
    1599             :                 const char *unit_name,
    1600             :                 sd_bus_error *error) {
    1601             : 
    1602           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    1603             :         const char *p;
    1604             :         int r;
    1605             : 
    1606           0 :         assert(m);
    1607           0 :         assert(w > 0);
    1608           0 :         assert(w < _INHIBIT_WHAT_MAX);
    1609           0 :         assert(unit_name);
    1610             : 
    1611           0 :         if (w == INHIBIT_SHUTDOWN)
    1612           0 :                 bus_manager_log_shutdown(m, unit_name);
    1613             : 
    1614           0 :         r = sd_bus_call_method(
    1615             :                         m->bus,
    1616             :                         "org.freedesktop.systemd1",
    1617             :                         "/org/freedesktop/systemd1",
    1618             :                         "org.freedesktop.systemd1.Manager",
    1619             :                         "StartUnit",
    1620             :                         error,
    1621             :                         &reply,
    1622             :                         "ss", unit_name, "replace-irreversibly");
    1623           0 :         if (r < 0)
    1624           0 :                 goto error;
    1625             : 
    1626           0 :         r = sd_bus_message_read(reply, "o", &p);
    1627           0 :         if (r < 0)
    1628           0 :                 goto error;
    1629             : 
    1630           0 :         r = free_and_strdup(&m->action_job, p);
    1631           0 :         if (r < 0)
    1632           0 :                 goto error;
    1633             : 
    1634           0 :         m->action_unit = unit_name;
    1635           0 :         m->action_what = w;
    1636             : 
    1637             :         /* Make sure the lid switch is ignored for a while */
    1638           0 :         manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
    1639             : 
    1640           0 :         return 0;
    1641             : 
    1642           0 : error:
    1643             :         /* Tell people that they now may take a lock again */
    1644           0 :         (void) send_prepare_for(m, w, false);
    1645             : 
    1646           0 :         return r;
    1647             : }
    1648             : 
    1649           0 : int manager_dispatch_delayed(Manager *manager, bool timeout) {
    1650             : 
    1651           0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    1652           0 :         Inhibitor *offending = NULL;
    1653             :         int r;
    1654             : 
    1655           0 :         assert(manager);
    1656             : 
    1657           0 :         if (manager->action_what == 0 || manager->action_job)
    1658           0 :                 return 0;
    1659             : 
    1660           0 :         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
    1661           0 :                 _cleanup_free_ char *comm = NULL, *u = NULL;
    1662             : 
    1663           0 :                 if (!timeout)
    1664           0 :                         return 0;
    1665             : 
    1666           0 :                 (void) get_process_comm(offending->pid, &comm);
    1667           0 :                 u = uid_to_name(offending->uid);
    1668             : 
    1669           0 :                 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
    1670             :                            offending->uid, strna(u),
    1671             :                            offending->pid, strna(comm));
    1672             :         }
    1673             : 
    1674             :         /* Actually do the operation */
    1675           0 :         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
    1676           0 :         if (r < 0) {
    1677           0 :                 log_warning("Error during inhibitor-delayed operation (already returned success to client): %s",
    1678             :                             bus_error_message(&error, r));
    1679             : 
    1680           0 :                 manager->action_unit = NULL;
    1681           0 :                 manager->action_what = 0;
    1682           0 :                 return r;
    1683             :         }
    1684             : 
    1685           0 :         return 1;
    1686             : }
    1687             : 
    1688           0 : static int manager_inhibit_timeout_handler(
    1689             :                         sd_event_source *s,
    1690             :                         uint64_t usec,
    1691             :                         void *userdata) {
    1692             : 
    1693           0 :         Manager *manager = userdata;
    1694             :         int r;
    1695             : 
    1696           0 :         assert(manager);
    1697           0 :         assert(manager->inhibit_timeout_source == s);
    1698             : 
    1699           0 :         r = manager_dispatch_delayed(manager, true);
    1700           0 :         return (r < 0) ? r : 0;
    1701             : }
    1702             : 
    1703           0 : static int delay_shutdown_or_sleep(
    1704             :                 Manager *m,
    1705             :                 InhibitWhat w,
    1706             :                 const char *unit_name) {
    1707             : 
    1708             :         int r;
    1709             :         usec_t timeout_val;
    1710             : 
    1711           0 :         assert(m);
    1712           0 :         assert(w >= 0);
    1713           0 :         assert(w < _INHIBIT_WHAT_MAX);
    1714           0 :         assert(unit_name);
    1715             : 
    1716           0 :         timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
    1717             : 
    1718           0 :         if (m->inhibit_timeout_source) {
    1719           0 :                 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
    1720           0 :                 if (r < 0)
    1721           0 :                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
    1722             : 
    1723           0 :                 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
    1724           0 :                 if (r < 0)
    1725           0 :                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
    1726             :         } else {
    1727           0 :                 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
    1728             :                                       timeout_val, 0, manager_inhibit_timeout_handler, m);
    1729           0 :                 if (r < 0)
    1730           0 :                         return r;
    1731             :         }
    1732             : 
    1733           0 :         m->action_unit = unit_name;
    1734           0 :         m->action_what = w;
    1735             : 
    1736           0 :         return 0;
    1737             : }
    1738             : 
    1739           0 : int bus_manager_shutdown_or_sleep_now_or_later(
    1740             :                 Manager *m,
    1741             :                 const char *unit_name,
    1742             :                 InhibitWhat w,
    1743             :                 sd_bus_error *error) {
    1744             : 
    1745           0 :         _cleanup_free_ char *load_state = NULL;
    1746             :         bool delayed;
    1747             :         int r;
    1748             : 
    1749           0 :         assert(m);
    1750           0 :         assert(unit_name);
    1751           0 :         assert(w > 0);
    1752           0 :         assert(w < _INHIBIT_WHAT_MAX);
    1753           0 :         assert(!m->action_job);
    1754             : 
    1755           0 :         r = unit_load_state(m->bus, unit_name, &load_state);
    1756           0 :         if (r < 0)
    1757           0 :                 return r;
    1758             : 
    1759           0 :         if (!streq(load_state, "loaded"))
    1760           0 :                 return log_notice_errno(SYNTHETIC_ERRNO(EACCES),
    1761             :                                         "Unit %s is %s, refusing operation.",
    1762             :                                         unit_name, load_state);
    1763             : 
    1764             :         /* Tell everybody to prepare for shutdown/sleep */
    1765           0 :         (void) send_prepare_for(m, w, true);
    1766             : 
    1767           0 :         delayed =
    1768           0 :                 m->inhibit_delay_max > 0 &&
    1769           0 :                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
    1770             : 
    1771           0 :         if (delayed)
    1772             :                 /* Shutdown is delayed, keep in mind what we
    1773             :                  * want to do, and start a timeout */
    1774           0 :                 r = delay_shutdown_or_sleep(m, w, unit_name);
    1775             :         else
    1776             :                 /* Shutdown is not delayed, execute it
    1777             :                  * immediately */
    1778           0 :                 r = execute_shutdown_or_sleep(m, w, unit_name, error);
    1779             : 
    1780           0 :         return r;
    1781             : }
    1782             : 
    1783           0 : static int verify_shutdown_creds(
    1784             :                 Manager *m,
    1785             :                 sd_bus_message *message,
    1786             :                 InhibitWhat w,
    1787             :                 bool interactive,
    1788             :                 const char *action,
    1789             :                 const char *action_multiple_sessions,
    1790             :                 const char *action_ignore_inhibit,
    1791             :                 sd_bus_error *error) {
    1792             : 
    1793           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
    1794             :         bool multiple_sessions, blocked;
    1795             :         uid_t uid;
    1796             :         int r;
    1797             : 
    1798           0 :         assert(m);
    1799           0 :         assert(message);
    1800           0 :         assert(w >= 0);
    1801           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    1802             : 
    1803           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
    1804           0 :         if (r < 0)
    1805           0 :                 return r;
    1806             : 
    1807           0 :         r = sd_bus_creds_get_euid(creds, &uid);
    1808           0 :         if (r < 0)
    1809           0 :                 return r;
    1810             : 
    1811           0 :         r = have_multiple_sessions(m, uid);
    1812           0 :         if (r < 0)
    1813           0 :                 return r;
    1814             : 
    1815           0 :         multiple_sessions = r > 0;
    1816           0 :         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
    1817             : 
    1818           0 :         if (multiple_sessions && action_multiple_sessions) {
    1819           0 :                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
    1820           0 :                 if (r < 0)
    1821           0 :                         return r;
    1822           0 :                 if (r == 0)
    1823           0 :                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1824             :         }
    1825             : 
    1826           0 :         if (blocked && action_ignore_inhibit) {
    1827           0 :                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
    1828           0 :                 if (r < 0)
    1829           0 :                         return r;
    1830           0 :                 if (r == 0)
    1831           0 :                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1832             :         }
    1833             : 
    1834           0 :         if (!multiple_sessions && !blocked && action) {
    1835           0 :                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
    1836           0 :                 if (r < 0)
    1837           0 :                         return r;
    1838           0 :                 if (r == 0)
    1839           0 :                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1840             :         }
    1841             : 
    1842           0 :         return 0;
    1843             : }
    1844             : 
    1845           0 : static int method_do_shutdown_or_sleep(
    1846             :                 Manager *m,
    1847             :                 sd_bus_message *message,
    1848             :                 const char *unit_name,
    1849             :                 InhibitWhat w,
    1850             :                 const char *action,
    1851             :                 const char *action_multiple_sessions,
    1852             :                 const char *action_ignore_inhibit,
    1853             :                 const char *sleep_verb,
    1854             :                 sd_bus_error *error) {
    1855             : 
    1856             :         int interactive, r;
    1857             : 
    1858           0 :         assert(m);
    1859           0 :         assert(message);
    1860           0 :         assert(unit_name);
    1861           0 :         assert(w >= 0);
    1862           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    1863             : 
    1864           0 :         r = sd_bus_message_read(message, "b", &interactive);
    1865           0 :         if (r < 0)
    1866           0 :                 return r;
    1867             : 
    1868             :         /* Don't allow multiple jobs being executed at the same time */
    1869           0 :         if (m->action_what > 0)
    1870           0 :                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS,
    1871             :                                          "There's already a shutdown or sleep operation in progress");
    1872             : 
    1873           0 :         if (sleep_verb) {
    1874           0 :                 r = can_sleep(sleep_verb);
    1875           0 :                 if (r == -ENOSPC)
    1876           0 :                         return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED,
    1877             :                                                 "Not enough swap space for hibernation");
    1878           0 :                 if (r == 0)
    1879           0 :                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED,
    1880             :                                                  "Sleep verb \"%s\" not supported", sleep_verb);
    1881           0 :                 if (r < 0)
    1882           0 :                         return r;
    1883             :         }
    1884             : 
    1885           0 :         r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
    1886             :                                   action_ignore_inhibit, error);
    1887           0 :         if (r != 0)
    1888           0 :                 return r;
    1889             : 
    1890           0 :         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
    1891           0 :         if (r < 0)
    1892           0 :                 return r;
    1893             : 
    1894           0 :         return sd_bus_reply_method_return(message, NULL);
    1895             : }
    1896             : 
    1897           0 : static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1898           0 :         Manager *m = userdata;
    1899             : 
    1900           0 :         return method_do_shutdown_or_sleep(
    1901             :                         m, message,
    1902             :                         SPECIAL_POWEROFF_TARGET,
    1903             :                         INHIBIT_SHUTDOWN,
    1904             :                         "org.freedesktop.login1.power-off",
    1905             :                         "org.freedesktop.login1.power-off-multiple-sessions",
    1906             :                         "org.freedesktop.login1.power-off-ignore-inhibit",
    1907             :                         NULL,
    1908             :                         error);
    1909             : }
    1910             : 
    1911           0 : static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1912           0 :         Manager *m = userdata;
    1913             : 
    1914           0 :         return method_do_shutdown_or_sleep(
    1915             :                         m, message,
    1916             :                         SPECIAL_REBOOT_TARGET,
    1917             :                         INHIBIT_SHUTDOWN,
    1918             :                         "org.freedesktop.login1.reboot",
    1919             :                         "org.freedesktop.login1.reboot-multiple-sessions",
    1920             :                         "org.freedesktop.login1.reboot-ignore-inhibit",
    1921             :                         NULL,
    1922             :                         error);
    1923             : }
    1924             : 
    1925           0 : static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1926           0 :         Manager *m = userdata;
    1927             : 
    1928           0 :         return method_do_shutdown_or_sleep(
    1929             :                         m, message,
    1930             :                         SPECIAL_HALT_TARGET,
    1931             :                         INHIBIT_SHUTDOWN,
    1932             :                         "org.freedesktop.login1.halt",
    1933             :                         "org.freedesktop.login1.halt-multiple-sessions",
    1934             :                         "org.freedesktop.login1.halt-ignore-inhibit",
    1935             :                         NULL,
    1936             :                         error);
    1937             : }
    1938             : 
    1939           0 : static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1940           0 :         Manager *m = userdata;
    1941             : 
    1942           0 :         return method_do_shutdown_or_sleep(
    1943             :                         m, message,
    1944             :                         SPECIAL_SUSPEND_TARGET,
    1945             :                         INHIBIT_SLEEP,
    1946             :                         "org.freedesktop.login1.suspend",
    1947             :                         "org.freedesktop.login1.suspend-multiple-sessions",
    1948             :                         "org.freedesktop.login1.suspend-ignore-inhibit",
    1949             :                         "suspend",
    1950             :                         error);
    1951             : }
    1952             : 
    1953           0 : static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1954           0 :         Manager *m = userdata;
    1955             : 
    1956           0 :         return method_do_shutdown_or_sleep(
    1957             :                         m, message,
    1958             :                         SPECIAL_HIBERNATE_TARGET,
    1959             :                         INHIBIT_SLEEP,
    1960             :                         "org.freedesktop.login1.hibernate",
    1961             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    1962             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    1963             :                         "hibernate",
    1964             :                         error);
    1965             : }
    1966             : 
    1967           0 : static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1968           0 :         Manager *m = userdata;
    1969             : 
    1970           0 :         return method_do_shutdown_or_sleep(
    1971             :                         m, message,
    1972             :                         SPECIAL_HYBRID_SLEEP_TARGET,
    1973             :                         INHIBIT_SLEEP,
    1974             :                         "org.freedesktop.login1.hibernate",
    1975             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    1976             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    1977             :                         "hybrid-sleep",
    1978             :                         error);
    1979             : }
    1980             : 
    1981           0 : static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1982           0 :         Manager *m = userdata;
    1983             : 
    1984           0 :         return method_do_shutdown_or_sleep(
    1985             :                         m, message,
    1986             :                         SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET,
    1987             :                         INHIBIT_SLEEP,
    1988             :                         "org.freedesktop.login1.hibernate",
    1989             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    1990             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    1991             :                         "hybrid-sleep",
    1992             :                         error);
    1993             : }
    1994             : 
    1995           0 : static int nologin_timeout_handler(
    1996             :                         sd_event_source *s,
    1997             :                         uint64_t usec,
    1998             :                         void *userdata) {
    1999             : 
    2000           0 :         Manager *m = userdata;
    2001             : 
    2002           0 :         log_info("Creating /run/nologin, blocking further logins...");
    2003             : 
    2004           0 :         m->unlink_nologin =
    2005           0 :                 create_shutdown_run_nologin_or_warn() >= 0;
    2006             : 
    2007           0 :         return 0;
    2008             : }
    2009             : 
    2010           0 : static int update_schedule_file(Manager *m) {
    2011           0 :         _cleanup_free_ char *temp_path = NULL;
    2012           0 :         _cleanup_fclose_ FILE *f = NULL;
    2013             :         int r;
    2014             : 
    2015           0 :         assert(m);
    2016             : 
    2017           0 :         r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0, MKDIR_WARN_MODE);
    2018           0 :         if (r < 0)
    2019           0 :                 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
    2020             : 
    2021           0 :         r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
    2022           0 :         if (r < 0)
    2023           0 :                 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
    2024             : 
    2025           0 :         (void) fchmod(fileno(f), 0644);
    2026             : 
    2027           0 :         fprintf(f,
    2028             :                 "USEC="USEC_FMT"\n"
    2029             :                 "WARN_WALL=%i\n"
    2030             :                 "MODE=%s\n",
    2031             :                 m->scheduled_shutdown_timeout,
    2032             :                 m->enable_wall_messages,
    2033             :                 m->scheduled_shutdown_type);
    2034             : 
    2035           0 :         if (!isempty(m->wall_message)) {
    2036           0 :                 _cleanup_free_ char *t;
    2037             : 
    2038           0 :                 t = cescape(m->wall_message);
    2039           0 :                 if (!t) {
    2040           0 :                         r = -ENOMEM;
    2041           0 :                         goto fail;
    2042             :                 }
    2043             : 
    2044           0 :                 fprintf(f, "WALL_MESSAGE=%s\n", t);
    2045             :         }
    2046             : 
    2047           0 :         r = fflush_and_check(f);
    2048           0 :         if (r < 0)
    2049           0 :                 goto fail;
    2050             : 
    2051           0 :         if (rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
    2052           0 :                 r = -errno;
    2053           0 :                 goto fail;
    2054             :         }
    2055             : 
    2056           0 :         return 0;
    2057             : 
    2058           0 : fail:
    2059           0 :         (void) unlink(temp_path);
    2060           0 :         (void) unlink("/run/systemd/shutdown/scheduled");
    2061             : 
    2062           0 :         return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
    2063             : }
    2064             : 
    2065           0 : static void reset_scheduled_shutdown(Manager *m) {
    2066           0 :         assert(m);
    2067             : 
    2068           0 :         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
    2069           0 :         m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
    2070           0 :         m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
    2071             : 
    2072           0 :         m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
    2073           0 :         m->scheduled_shutdown_timeout = 0;
    2074           0 :         m->shutdown_dry_run = false;
    2075             : 
    2076           0 :         if (m->unlink_nologin) {
    2077           0 :                 (void) unlink_or_warn("/run/nologin");
    2078           0 :                 m->unlink_nologin = false;
    2079             :         }
    2080             : 
    2081           0 :         (void) unlink("/run/systemd/shutdown/scheduled");
    2082           0 : }
    2083             : 
    2084           0 : static int manager_scheduled_shutdown_handler(
    2085             :                         sd_event_source *s,
    2086             :                         uint64_t usec,
    2087             :                         void *userdata) {
    2088             : 
    2089           0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    2090           0 :         Manager *m = userdata;
    2091             :         const char *target;
    2092             :         int r;
    2093             : 
    2094           0 :         assert(m);
    2095             : 
    2096           0 :         if (isempty(m->scheduled_shutdown_type))
    2097           0 :                 return 0;
    2098             : 
    2099           0 :         if (streq(m->scheduled_shutdown_type, "poweroff"))
    2100           0 :                 target = SPECIAL_POWEROFF_TARGET;
    2101           0 :         else if (streq(m->scheduled_shutdown_type, "reboot"))
    2102           0 :                 target = SPECIAL_REBOOT_TARGET;
    2103           0 :         else if (streq(m->scheduled_shutdown_type, "halt"))
    2104           0 :                 target = SPECIAL_HALT_TARGET;
    2105             :         else
    2106           0 :                 assert_not_reached("unexpected shutdown type");
    2107             : 
    2108             :         /* Don't allow multiple jobs being executed at the same time */
    2109           0 :         if (m->action_what > 0) {
    2110           0 :                 r = -EALREADY;
    2111           0 :                 log_error("Scheduled shutdown to %s failed: shutdown or sleep operation already in progress", target);
    2112           0 :                 goto error;
    2113             :         }
    2114             : 
    2115           0 :         if (m->shutdown_dry_run) {
    2116             :                 /* We do not process delay inhibitors here.  Otherwise, we
    2117             :                  * would have to be considered "in progress" (like the check
    2118             :                  * above) for some seconds after our admin has seen the final
    2119             :                  * wall message. */
    2120             : 
    2121           0 :                 bus_manager_log_shutdown(m, target);
    2122           0 :                 log_info("Running in dry run, suppressing action.");
    2123           0 :                 reset_scheduled_shutdown(m);
    2124             : 
    2125           0 :                 return 0;
    2126             :         }
    2127             : 
    2128           0 :         r = bus_manager_shutdown_or_sleep_now_or_later(m, target, INHIBIT_SHUTDOWN, &error);
    2129           0 :         if (r < 0) {
    2130           0 :                 log_error_errno(r, "Scheduled shutdown to %s failed: %m", target);
    2131           0 :                 goto error;
    2132             :         }
    2133             : 
    2134           0 :         return 0;
    2135             : 
    2136           0 : error:
    2137           0 :         reset_scheduled_shutdown(m);
    2138           0 :         return r;
    2139             : }
    2140             : 
    2141           0 : static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2142           0 :         Manager *m = userdata;
    2143           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
    2144           0 :         const char *action_multiple_sessions = NULL;
    2145           0 :         const char *action_ignore_inhibit = NULL;
    2146           0 :         const char *action = NULL;
    2147             :         uint64_t elapse;
    2148             :         char *type;
    2149             :         int r;
    2150           0 :         bool dry_run = false;
    2151             : 
    2152           0 :         assert(m);
    2153           0 :         assert(message);
    2154             : 
    2155           0 :         r = sd_bus_message_read(message, "st", &type, &elapse);
    2156           0 :         if (r < 0)
    2157           0 :                 return r;
    2158             : 
    2159           0 :         if (startswith(type, "dry-")) {
    2160           0 :                 type += 4;
    2161           0 :                 dry_run = true;
    2162             :         }
    2163             : 
    2164           0 :         if (streq(type, "poweroff")) {
    2165           0 :                 action = "org.freedesktop.login1.power-off";
    2166           0 :                 action_multiple_sessions = "org.freedesktop.login1.power-off-multiple-sessions";
    2167           0 :                 action_ignore_inhibit = "org.freedesktop.login1.power-off-ignore-inhibit";
    2168           0 :         } else if (streq(type, "reboot")) {
    2169           0 :                 action = "org.freedesktop.login1.reboot";
    2170           0 :                 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
    2171           0 :                 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
    2172           0 :         } else if (streq(type, "halt")) {
    2173           0 :                 action = "org.freedesktop.login1.halt";
    2174           0 :                 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
    2175           0 :                 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
    2176             :         } else
    2177           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
    2178             : 
    2179           0 :         r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
    2180             :                                   action, action_multiple_sessions, action_ignore_inhibit, error);
    2181           0 :         if (r != 0)
    2182           0 :                 return r;
    2183             : 
    2184           0 :         if (m->scheduled_shutdown_timeout_source) {
    2185           0 :                 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
    2186           0 :                 if (r < 0)
    2187           0 :                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
    2188             : 
    2189           0 :                 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
    2190           0 :                 if (r < 0)
    2191           0 :                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
    2192             :         } else {
    2193           0 :                 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
    2194             :                                       CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
    2195           0 :                 if (r < 0)
    2196           0 :                         return log_error_errno(r, "sd_event_add_time() failed: %m");
    2197             :         }
    2198             : 
    2199           0 :         r = free_and_strdup(&m->scheduled_shutdown_type, type);
    2200           0 :         if (r < 0) {
    2201           0 :                 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
    2202           0 :                 return log_oom();
    2203             :         }
    2204             : 
    2205           0 :         m->shutdown_dry_run = dry_run;
    2206             : 
    2207           0 :         if (m->nologin_timeout_source) {
    2208           0 :                 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
    2209           0 :                 if (r < 0)
    2210           0 :                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
    2211             : 
    2212           0 :                 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
    2213           0 :                 if (r < 0)
    2214           0 :                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
    2215             :         } else {
    2216           0 :                 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
    2217             :                                       CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
    2218           0 :                 if (r < 0)
    2219           0 :                         return log_error_errno(r, "sd_event_add_time() failed: %m");
    2220             :         }
    2221             : 
    2222           0 :         m->scheduled_shutdown_timeout = elapse;
    2223             : 
    2224           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
    2225           0 :         if (r >= 0) {
    2226           0 :                 const char *tty = NULL;
    2227             : 
    2228           0 :                 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
    2229           0 :                 (void) sd_bus_creds_get_tty(creds, &tty);
    2230             : 
    2231           0 :                 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
    2232           0 :                 if (r < 0) {
    2233           0 :                         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
    2234           0 :                         return log_oom();
    2235             :                 }
    2236             :         }
    2237             : 
    2238           0 :         r = manager_setup_wall_message_timer(m);
    2239           0 :         if (r < 0)
    2240           0 :                 return r;
    2241             : 
    2242           0 :         r = update_schedule_file(m);
    2243           0 :         if (r < 0)
    2244           0 :                 return r;
    2245             : 
    2246           0 :         return sd_bus_reply_method_return(message, NULL);
    2247             : }
    2248             : 
    2249           0 : static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2250           0 :         Manager *m = userdata;
    2251             :         bool cancelled;
    2252             : 
    2253           0 :         assert(m);
    2254           0 :         assert(message);
    2255             : 
    2256           0 :         cancelled = m->scheduled_shutdown_type != NULL;
    2257           0 :         reset_scheduled_shutdown(m);
    2258             : 
    2259           0 :         if (cancelled && m->enable_wall_messages) {
    2260           0 :                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
    2261           0 :                 _cleanup_free_ char *username = NULL;
    2262           0 :                 const char *tty = NULL;
    2263           0 :                 uid_t uid = 0;
    2264             :                 int r;
    2265             : 
    2266           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
    2267           0 :                 if (r >= 0) {
    2268           0 :                         (void) sd_bus_creds_get_uid(creds, &uid);
    2269           0 :                         (void) sd_bus_creds_get_tty(creds, &tty);
    2270             :                 }
    2271             : 
    2272           0 :                 username = uid_to_name(uid);
    2273           0 :                 utmp_wall("The system shutdown has been cancelled",
    2274             :                           username, tty, logind_wall_tty_filter, m);
    2275             :         }
    2276             : 
    2277           0 :         return sd_bus_reply_method_return(message, "b", cancelled);
    2278             : }
    2279             : 
    2280           0 : static int method_can_shutdown_or_sleep(
    2281             :                 Manager *m,
    2282             :                 sd_bus_message *message,
    2283             :                 InhibitWhat w,
    2284             :                 const char *action,
    2285             :                 const char *action_multiple_sessions,
    2286             :                 const char *action_ignore_inhibit,
    2287             :                 const char *sleep_verb,
    2288             :                 sd_bus_error *error) {
    2289             : 
    2290           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
    2291             :         HandleAction handle;
    2292             :         bool multiple_sessions, challenge, blocked;
    2293           0 :         const char *result = NULL;
    2294             :         uid_t uid;
    2295             :         int r;
    2296             : 
    2297           0 :         assert(m);
    2298           0 :         assert(message);
    2299           0 :         assert(w >= 0);
    2300           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    2301           0 :         assert(action);
    2302           0 :         assert(action_multiple_sessions);
    2303           0 :         assert(action_ignore_inhibit);
    2304             : 
    2305           0 :         if (sleep_verb) {
    2306           0 :                 r = can_sleep(sleep_verb);
    2307           0 :                 if (IN_SET(r,  0, -ENOSPC))
    2308           0 :                         return sd_bus_reply_method_return(message, "s", "na");
    2309           0 :                 if (r < 0)
    2310           0 :                         return r;
    2311             :         }
    2312             : 
    2313           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
    2314           0 :         if (r < 0)
    2315           0 :                 return r;
    2316             : 
    2317           0 :         r = sd_bus_creds_get_euid(creds, &uid);
    2318           0 :         if (r < 0)
    2319           0 :                 return r;
    2320             : 
    2321           0 :         r = have_multiple_sessions(m, uid);
    2322           0 :         if (r < 0)
    2323           0 :                 return r;
    2324             : 
    2325           0 :         multiple_sessions = r > 0;
    2326           0 :         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
    2327             : 
    2328           0 :         handle = handle_action_from_string(sleep_verb);
    2329           0 :         if (handle >= 0) {
    2330             :                 const char *target;
    2331             : 
    2332           0 :                 target = manager_target_for_action(handle);
    2333           0 :                 if (target) {
    2334           0 :                         _cleanup_free_ char *load_state = NULL;
    2335             : 
    2336           0 :                         r = unit_load_state(m->bus, target, &load_state);
    2337           0 :                         if (r < 0)
    2338           0 :                                 return r;
    2339             : 
    2340           0 :                         if (!streq(load_state, "loaded")) {
    2341           0 :                                 result = "no";
    2342           0 :                                 goto finish;
    2343             :                         }
    2344             :                 }
    2345             :         }
    2346             : 
    2347           0 :         if (multiple_sessions) {
    2348           0 :                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error);
    2349           0 :                 if (r < 0)
    2350           0 :                         return r;
    2351             : 
    2352           0 :                 if (r > 0)
    2353           0 :                         result = "yes";
    2354           0 :                 else if (challenge)
    2355           0 :                         result = "challenge";
    2356             :                 else
    2357           0 :                         result = "no";
    2358             :         }
    2359             : 
    2360           0 :         if (blocked) {
    2361           0 :                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error);
    2362           0 :                 if (r < 0)
    2363           0 :                         return r;
    2364             : 
    2365           0 :                 if (r > 0) {
    2366           0 :                         if (!result)
    2367           0 :                                 result = "yes";
    2368           0 :                 } else if (challenge) {
    2369           0 :                         if (!result || streq(result, "yes"))
    2370           0 :                                 result = "challenge";
    2371             :                 } else
    2372           0 :                         result = "no";
    2373             :         }
    2374             : 
    2375           0 :         if (!multiple_sessions && !blocked) {
    2376             :                 /* If neither inhibit nor multiple sessions
    2377             :                  * apply then just check the normal policy */
    2378             : 
    2379           0 :                 r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error);
    2380           0 :                 if (r < 0)
    2381           0 :                         return r;
    2382             : 
    2383           0 :                 if (r > 0)
    2384           0 :                         result = "yes";
    2385           0 :                 else if (challenge)
    2386           0 :                         result = "challenge";
    2387             :                 else
    2388           0 :                         result = "no";
    2389             :         }
    2390             : 
    2391           0 :  finish:
    2392           0 :         return sd_bus_reply_method_return(message, "s", result);
    2393             : }
    2394             : 
    2395           0 : static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2396           0 :         Manager *m = userdata;
    2397             : 
    2398           0 :         return method_can_shutdown_or_sleep(
    2399             :                         m, message,
    2400             :                         INHIBIT_SHUTDOWN,
    2401             :                         "org.freedesktop.login1.power-off",
    2402             :                         "org.freedesktop.login1.power-off-multiple-sessions",
    2403             :                         "org.freedesktop.login1.power-off-ignore-inhibit",
    2404             :                         NULL,
    2405             :                         error);
    2406             : }
    2407             : 
    2408           0 : static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2409           0 :         Manager *m = userdata;
    2410             : 
    2411           0 :         return method_can_shutdown_or_sleep(
    2412             :                         m, message,
    2413             :                         INHIBIT_SHUTDOWN,
    2414             :                         "org.freedesktop.login1.reboot",
    2415             :                         "org.freedesktop.login1.reboot-multiple-sessions",
    2416             :                         "org.freedesktop.login1.reboot-ignore-inhibit",
    2417             :                         NULL,
    2418             :                         error);
    2419             : }
    2420             : 
    2421           0 : static int method_can_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2422           0 :         Manager *m = userdata;
    2423             : 
    2424           0 :         return method_can_shutdown_or_sleep(
    2425             :                         m, message,
    2426             :                         INHIBIT_SHUTDOWN,
    2427             :                         "org.freedesktop.login1.halt",
    2428             :                         "org.freedesktop.login1.halt-multiple-sessions",
    2429             :                         "org.freedesktop.login1.halt-ignore-inhibit",
    2430             :                         NULL,
    2431             :                         error);
    2432             : }
    2433             : 
    2434           0 : static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2435           0 :         Manager *m = userdata;
    2436             : 
    2437           0 :         return method_can_shutdown_or_sleep(
    2438             :                         m, message,
    2439             :                         INHIBIT_SLEEP,
    2440             :                         "org.freedesktop.login1.suspend",
    2441             :                         "org.freedesktop.login1.suspend-multiple-sessions",
    2442             :                         "org.freedesktop.login1.suspend-ignore-inhibit",
    2443             :                         "suspend",
    2444             :                         error);
    2445             : }
    2446             : 
    2447           0 : static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2448           0 :         Manager *m = userdata;
    2449             : 
    2450           0 :         return method_can_shutdown_or_sleep(
    2451             :                         m, message,
    2452             :                         INHIBIT_SLEEP,
    2453             :                         "org.freedesktop.login1.hibernate",
    2454             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2455             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2456             :                         "hibernate",
    2457             :                         error);
    2458             : }
    2459             : 
    2460           0 : static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2461           0 :         Manager *m = userdata;
    2462             : 
    2463           0 :         return method_can_shutdown_or_sleep(
    2464             :                         m, message,
    2465             :                         INHIBIT_SLEEP,
    2466             :                         "org.freedesktop.login1.hibernate",
    2467             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2468             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2469             :                         "hybrid-sleep",
    2470             :                         error);
    2471             : }
    2472             : 
    2473           0 : static int method_can_suspend_then_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2474           0 :         Manager *m = userdata;
    2475             : 
    2476           0 :         return method_can_shutdown_or_sleep(
    2477             :                         m, message,
    2478             :                         INHIBIT_SLEEP,
    2479             :                         "org.freedesktop.login1.hibernate",
    2480             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2481             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2482             :                         "suspend-then-hibernate",
    2483             :                         error);
    2484             : }
    2485             : 
    2486           0 : static int property_get_reboot_parameter(
    2487             :                 sd_bus *bus,
    2488             :                 const char *path,
    2489             :                 const char *interface,
    2490             :                 const char *property,
    2491             :                 sd_bus_message *reply,
    2492             :                 void *userdata,
    2493             :                 sd_bus_error *error) {
    2494           0 :         _cleanup_free_ char *parameter = NULL;
    2495             :         int r;
    2496             : 
    2497           0 :         assert(bus);
    2498           0 :         assert(reply);
    2499           0 :         assert(userdata);
    2500             : 
    2501           0 :         r = read_reboot_parameter(&parameter);
    2502           0 :         if (r < 0)
    2503           0 :                 return r;
    2504             : 
    2505           0 :         return sd_bus_message_append(reply, "s", parameter);
    2506             : }
    2507             : 
    2508           0 : static int method_set_reboot_parameter(
    2509             :                 sd_bus_message *message,
    2510             :                 void *userdata,
    2511             :                 sd_bus_error *error) {
    2512             : 
    2513           0 :         Manager *m = userdata;
    2514             :         const char *arg;
    2515             :         int r;
    2516             : 
    2517           0 :         assert(message);
    2518           0 :         assert(m);
    2519             : 
    2520           0 :         r = sd_bus_message_read(message, "s", &arg);
    2521           0 :         if (r < 0)
    2522           0 :                 return r;
    2523             : 
    2524           0 :         r = detect_container();
    2525           0 :         if (r < 0)
    2526           0 :                 return r;
    2527           0 :         if (r > 0)
    2528           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
    2529             :                                          "Reboot parameter not supported in containers, refusing.");
    2530             : 
    2531           0 :         r = bus_verify_polkit_async(message,
    2532             :                                     CAP_SYS_ADMIN,
    2533             :                                     "org.freedesktop.login1.set-reboot-parameter",
    2534             :                                     NULL,
    2535             :                                     false,
    2536             :                                     UID_INVALID,
    2537             :                                     &m->polkit_registry,
    2538             :                                     error);
    2539           0 :         if (r < 0)
    2540           0 :                 return r;
    2541           0 :         if (r == 0)
    2542           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2543             : 
    2544           0 :         r = update_reboot_parameter_and_warn(arg, false);
    2545           0 :         if (r < 0)
    2546           0 :                 return r;
    2547             : 
    2548           0 :         return sd_bus_reply_method_return(message, NULL);
    2549             : }
    2550             : 
    2551           0 : static int method_can_reboot_parameter(
    2552             :                 sd_bus_message *message,
    2553             :                 void *userdata,
    2554             :                 sd_bus_error *error) {
    2555             : 
    2556           0 :         Manager *m = userdata;
    2557             :         int r;
    2558             : 
    2559           0 :         assert(message);
    2560           0 :         assert(m);
    2561             : 
    2562           0 :         r = detect_container();
    2563           0 :         if (r < 0)
    2564           0 :                 return r;
    2565           0 :         if (r > 0) /* Inside containers, specifying a reboot parameter, doesn't make much sense */
    2566           0 :                 return sd_bus_reply_method_return(message, "s", "na");
    2567             : 
    2568           0 :         return return_test_polkit(
    2569             :                         message,
    2570             :                         CAP_SYS_ADMIN,
    2571             :                         "org.freedesktop.login1.set-reboot-parameter",
    2572             :                         NULL,
    2573             :                         UID_INVALID,
    2574             :                         error);
    2575             : }
    2576             : 
    2577           0 : static int property_get_reboot_to_firmware_setup(
    2578             :                 sd_bus *bus,
    2579             :                 const char *path,
    2580             :                 const char *interface,
    2581             :                 const char *property,
    2582             :                 sd_bus_message *reply,
    2583             :                 void *userdata,
    2584             :                 sd_bus_error *error) {
    2585             :         int r;
    2586             : 
    2587           0 :         assert(bus);
    2588           0 :         assert(reply);
    2589           0 :         assert(userdata);
    2590             : 
    2591           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_FIRMWARE_SETUP");
    2592           0 :         if (r == -ENXIO) {
    2593             :                 /* EFI case: let's see what is currently configured in the EFI variables */
    2594           0 :                 r = efi_get_reboot_to_firmware();
    2595           0 :                 if (r < 0 && r != -EOPNOTSUPP)
    2596           0 :                         log_warning_errno(r, "Failed to determine reboot-to-firmware-setup state: %m");
    2597           0 :         } else if (r < 0)
    2598           0 :                 log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP: %m");
    2599           0 :         else if (r > 0) {
    2600             :                 /* Non-EFI case: let's see whether /run/systemd/reboot-to-firmware-setup exists. */
    2601           0 :                 if (access("/run/systemd/reboot-to-firmware-setup", F_OK) < 0) {
    2602           0 :                         if (errno != ENOENT)
    2603           0 :                                 log_warning_errno(errno, "Failed to check whether /run/systemd/reboot-to-firmware-setup exists: %m");
    2604             : 
    2605           0 :                         r = false;
    2606             :                 } else
    2607           0 :                         r = true;
    2608             :         }
    2609             : 
    2610           0 :         return sd_bus_message_append(reply, "b", r > 0);
    2611             : }
    2612             : 
    2613           0 : static int method_set_reboot_to_firmware_setup(
    2614             :                 sd_bus_message *message,
    2615             :                 void *userdata,
    2616             :                 sd_bus_error *error) {
    2617             : 
    2618           0 :         Manager *m = userdata;
    2619             :         bool use_efi;
    2620             :         int b, r;
    2621             : 
    2622           0 :         assert(message);
    2623           0 :         assert(m);
    2624             : 
    2625           0 :         r = sd_bus_message_read(message, "b", &b);
    2626           0 :         if (r < 0)
    2627           0 :                 return r;
    2628             : 
    2629           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_FIRMWARE_SETUP");
    2630           0 :         if (r == -ENXIO) {
    2631             :                 /* EFI case: let's see what the firmware supports */
    2632             : 
    2633           0 :                 r = efi_reboot_to_firmware_supported();
    2634           0 :                 if (r == -EOPNOTSUPP)
    2635           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Firmware does not support boot into firmware.");
    2636           0 :                 if (r < 0)
    2637           0 :                         return r;
    2638             : 
    2639           0 :                 use_efi = true;
    2640             : 
    2641           0 :         } else if (r <= 0) {
    2642             :                 /* non-EFI case: $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP is set to off */
    2643             : 
    2644           0 :                 if (r < 0)
    2645           0 :                         log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP: %m");
    2646             : 
    2647           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Firmware does not support boot into firmware.");
    2648             :         } else
    2649             :                 /* non-EFI case: $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP is set to on */
    2650           0 :                 use_efi = false;
    2651             : 
    2652           0 :         r = bus_verify_polkit_async(message,
    2653             :                                     CAP_SYS_ADMIN,
    2654             :                                     "org.freedesktop.login1.set-reboot-to-firmware-setup",
    2655             :                                     NULL,
    2656             :                                     false,
    2657             :                                     UID_INVALID,
    2658             :                                     &m->polkit_registry,
    2659             :                                     error);
    2660           0 :         if (r < 0)
    2661           0 :                 return r;
    2662           0 :         if (r == 0)
    2663           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2664             : 
    2665           0 :         if (use_efi) {
    2666           0 :                 r = efi_set_reboot_to_firmware(b);
    2667           0 :                 if (r < 0)
    2668           0 :                         return r;
    2669             :         } else {
    2670           0 :                 if (b) {
    2671           0 :                         r = touch("/run/systemd/reboot-to-firmware-setup");
    2672           0 :                         if (r < 0)
    2673           0 :                                 return r;
    2674             :                 } else {
    2675           0 :                         if (unlink("/run/systemd/reboot-to-firmware-setup") < 0 && errno != ENOENT)
    2676           0 :                                 return -errno;
    2677             :                 }
    2678             :         }
    2679             : 
    2680           0 :         return sd_bus_reply_method_return(message, NULL);
    2681             : }
    2682             : 
    2683           0 : static int method_can_reboot_to_firmware_setup(
    2684             :                 sd_bus_message *message,
    2685             :                 void *userdata,
    2686             :                 sd_bus_error *error) {
    2687             : 
    2688           0 :         Manager *m = userdata;
    2689             :         int r;
    2690             : 
    2691           0 :         assert(message);
    2692           0 :         assert(m);
    2693             : 
    2694           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_FIRMWARE_SETUP");
    2695           0 :         if (r == -ENXIO) {
    2696             :                 /* EFI case: let's see what the firmware supports */
    2697             : 
    2698           0 :                 r = efi_reboot_to_firmware_supported();
    2699           0 :                 if (r < 0) {
    2700           0 :                         if (r != -EOPNOTSUPP)
    2701           0 :                                 log_warning_errno(r, "Failed to determine whether reboot to firmware is supported: %m");
    2702             : 
    2703           0 :                         return sd_bus_reply_method_return(message, "s", "na");
    2704             :                 }
    2705             : 
    2706           0 :         } else if (r <= 0) {
    2707             :                 /* Non-EFI case: let's trust $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP */
    2708             : 
    2709           0 :                 if (r < 0)
    2710           0 :                         log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_FIRMWARE_SETUP: %m");
    2711             : 
    2712           0 :                 return sd_bus_reply_method_return(message, "s", "na");
    2713             :         }
    2714             : 
    2715           0 :         return return_test_polkit(
    2716             :                         message,
    2717             :                         CAP_SYS_ADMIN,
    2718             :                         "org.freedesktop.login1.set-reboot-to-firmware-setup",
    2719             :                         NULL,
    2720             :                         UID_INVALID,
    2721             :                         error);
    2722             : }
    2723             : 
    2724           0 : static int property_get_reboot_to_boot_loader_menu(
    2725             :                 sd_bus *bus,
    2726             :                 const char *path,
    2727             :                 const char *interface,
    2728             :                 const char *property,
    2729             :                 sd_bus_message *reply,
    2730             :                 void *userdata,
    2731             :                 sd_bus_error *error) {
    2732             : 
    2733           0 :         uint64_t x = UINT64_MAX;
    2734             :         int r;
    2735             : 
    2736           0 :         assert(bus);
    2737           0 :         assert(reply);
    2738           0 :         assert(userdata);
    2739             : 
    2740           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU");
    2741           0 :         if (r == -ENXIO) {
    2742           0 :                 _cleanup_free_ char *v = NULL;
    2743             : 
    2744             :                 /* EFI case: returns the current value of LoaderConfigTimeoutOneShot. Three cases are distuingished:
    2745             :                  *
    2746             :                  *     1. Variable not set, boot into boot loader menu is not enabled (we return UINT64_MAX to the user)
    2747             :                  *     2. Variable set to "0", boot into boot loader menu is enabled with no timeout (we return 0 to the user)
    2748             :                  *     3. Variable set to numeric value formatted in ASCII, boot into boot loader menu with the specified timeout in seconds
    2749             :                  */
    2750             : 
    2751           0 :                 r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot", &v);
    2752           0 :                 if (r < 0) {
    2753           0 :                         if (r != -ENOENT)
    2754           0 :                                 log_warning_errno(r, "Failed to read LoaderConfigTimeoutOneShot variable: %m");
    2755             :                 } else {
    2756             :                         uint64_t sec;
    2757             : 
    2758           0 :                         r = safe_atou64(v, &sec);
    2759           0 :                         if (r < 0)
    2760           0 :                                 log_warning_errno(r, "Failed to parse LoaderConfigTimeoutOneShot value '%s': %m", v);
    2761           0 :                         else if (sec > (USEC_INFINITY / USEC_PER_SEC))
    2762           0 :                                 log_warning("LoaderConfigTimeoutOneShot too large, ignoring: %m");
    2763             :                         else
    2764           0 :                                 x = sec * USEC_PER_SEC; /* return in µs */
    2765             :                 }
    2766             : 
    2767           0 :         } else if (r < 0)
    2768           0 :                 log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU: %m");
    2769           0 :         else if (r > 0) {
    2770           0 :                 _cleanup_free_ char *v = NULL;
    2771             : 
    2772             :                 /* Non-EFI case, let's process /run/systemd/reboot-to-boot-loader-menu. */
    2773             : 
    2774           0 :                 r = read_one_line_file("/run/systemd/reboot-to-boot-loader-menu", &v);
    2775           0 :                 if (r < 0) {
    2776           0 :                         if (r != -ENOENT)
    2777           0 :                                 log_warning_errno(r, "Failed to read /run/systemd/reboot-to-boot-loader-menu: %m");
    2778             :                 } else {
    2779           0 :                         r = safe_atou64(v, &x);
    2780           0 :                         if (r < 0)
    2781           0 :                                 log_warning_errno(r, "Failed to parse /run/systemd/reboot-to-boot-loader-menu: %m");
    2782             :                 }
    2783             :         }
    2784             : 
    2785           0 :         return sd_bus_message_append(reply, "t", x);
    2786             : }
    2787             : 
    2788           0 : static int method_set_reboot_to_boot_loader_menu(
    2789             :                 sd_bus_message *message,
    2790             :                 void *userdata,
    2791             :                 sd_bus_error *error) {
    2792             : 
    2793           0 :         Manager *m = userdata;
    2794             :         bool use_efi;
    2795             :         uint64_t x;
    2796             :         int r;
    2797             : 
    2798           0 :         assert(message);
    2799           0 :         assert(m);
    2800             : 
    2801           0 :         r = sd_bus_message_read(message, "t", &x);
    2802           0 :         if (r < 0)
    2803           0 :                 return r;
    2804             : 
    2805           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU");
    2806           0 :         if (r == -ENXIO) {
    2807             :                 uint64_t features;
    2808             : 
    2809             :                 /* EFI case: let's see if booting into boot loader menu is supported. */
    2810             : 
    2811           0 :                 r = efi_loader_get_features(&features);
    2812           0 :                 if (r < 0)
    2813           0 :                         log_warning_errno(r, "Failed to determine whether reboot to boot loader menu is supported: %m");
    2814           0 :                 if (r < 0 || !FLAGS_SET(features, EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT))
    2815           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Boot loader does not support boot into boot loader menu.");
    2816             : 
    2817           0 :                 use_efi = true;
    2818             : 
    2819           0 :         } else if (r <= 0) {
    2820             :                 /* non-EFI case: $SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU is set to off */
    2821             : 
    2822           0 :                 if (r < 0)
    2823           0 :                         log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU: %m");
    2824             : 
    2825           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Boot loader does not support boot into boot loader menu.");
    2826             :         } else
    2827             :                 /* non-EFI case: $SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU is set to on */
    2828           0 :                 use_efi = false;
    2829             : 
    2830           0 :         r = bus_verify_polkit_async(message,
    2831             :                                     CAP_SYS_ADMIN,
    2832             :                                     "org.freedesktop.login1.set-reboot-to-boot-loader-menu",
    2833             :                                     NULL,
    2834             :                                     false,
    2835             :                                     UID_INVALID,
    2836             :                                     &m->polkit_registry,
    2837             :                                     error);
    2838           0 :         if (r < 0)
    2839           0 :                 return r;
    2840           0 :         if (r == 0)
    2841           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2842             : 
    2843           0 :         if (use_efi) {
    2844           0 :                 if (x == UINT64_MAX)
    2845           0 :                         r = efi_set_variable(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot", NULL, 0);
    2846             :                 else {
    2847             :                         char buf[DECIMAL_STR_MAX(uint64_t) + 1];
    2848           0 :                         xsprintf(buf, "%" PRIu64, DIV_ROUND_UP(x, USEC_PER_SEC)); /* second granularity */
    2849             : 
    2850           0 :                         r = efi_set_variable_string(EFI_VENDOR_LOADER, "LoaderConfigTimeoutOneShot", buf);
    2851             :                 }
    2852           0 :                 if (r < 0)
    2853           0 :                         return r;
    2854             :         } else {
    2855           0 :                 if (x == UINT64_MAX) {
    2856           0 :                         if (unlink("/run/systemd/reboot-to-loader-menu") < 0 && errno != ENOENT)
    2857           0 :                                 return -errno;
    2858             :                 } else {
    2859             :                         char buf[DECIMAL_STR_MAX(uint64_t) + 1];
    2860             : 
    2861           0 :                         xsprintf(buf, "%" PRIu64, x); /* µs granularity */
    2862             : 
    2863           0 :                         r = write_string_file_atomic_label("/run/systemd/reboot-to-loader-menu", buf);
    2864           0 :                         if (r < 0)
    2865           0 :                                 return r;
    2866             :                 }
    2867             :         }
    2868             : 
    2869           0 :         return sd_bus_reply_method_return(message, NULL);
    2870             : }
    2871             : 
    2872           0 : static int method_can_reboot_to_boot_loader_menu(
    2873             :                 sd_bus_message *message,
    2874             :                 void *userdata,
    2875             :                 sd_bus_error *error) {
    2876             : 
    2877           0 :         Manager *m = userdata;
    2878             :         int r;
    2879             : 
    2880           0 :         assert(message);
    2881           0 :         assert(m);
    2882             : 
    2883           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU");
    2884           0 :         if (r == -ENXIO) {
    2885           0 :                 uint64_t features = 0;
    2886             : 
    2887             :                 /* EFI case, let's see if booting into boot loader menu is supported. */
    2888             : 
    2889           0 :                 r = efi_loader_get_features(&features);
    2890           0 :                 if (r < 0)
    2891           0 :                         log_warning_errno(r, "Failed to determine whether reboot to boot loader menu is supported: %m");
    2892           0 :                 if (r < 0 || !FLAGS_SET(features, EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT))
    2893           0 :                         return sd_bus_reply_method_return(message, "s", "na");
    2894             : 
    2895           0 :         } else if (r <= 0) {
    2896             :                 /* Non-EFI case: let's trust $SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU */
    2897             : 
    2898           0 :                 if (r < 0)
    2899           0 :                         log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU: %m");
    2900             : 
    2901           0 :                 return sd_bus_reply_method_return(message, "s", "na");
    2902             :         }
    2903             : 
    2904           0 :         return return_test_polkit(
    2905             :                         message,
    2906             :                         CAP_SYS_ADMIN,
    2907             :                         "org.freedesktop.login1.set-reboot-to-boot-loader-menu",
    2908             :                         NULL,
    2909             :                         UID_INVALID,
    2910             :                         error);
    2911             : }
    2912             : 
    2913           0 : static int property_get_reboot_to_boot_loader_entry(
    2914             :                 sd_bus *bus,
    2915             :                 const char *path,
    2916             :                 const char *interface,
    2917             :                 const char *property,
    2918             :                 sd_bus_message *reply,
    2919             :                 void *userdata,
    2920             :                 sd_bus_error *error) {
    2921             : 
    2922           0 :         _cleanup_free_ char *v = NULL;
    2923             :         int r;
    2924             : 
    2925           0 :         assert(bus);
    2926           0 :         assert(reply);
    2927           0 :         assert(userdata);
    2928             : 
    2929           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY");
    2930           0 :         if (r == -ENXIO) {
    2931             :                 /* EFI case: let's read the LoaderEntryOneShot variable */
    2932             : 
    2933           0 :                 r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", &v);
    2934           0 :                 if (r < 0) {
    2935           0 :                         if (r != -ENOENT)
    2936           0 :                                 log_warning_errno(r, "Failed to read LoaderEntryOneShot variable: %m");
    2937           0 :                 } else if (!efi_loader_entry_name_valid(v)) {
    2938           0 :                         log_warning("LoaderEntryOneShot contains invalid entry name '%s', ignoring.", v);
    2939           0 :                         v = mfree(v);
    2940             :                 }
    2941           0 :         } else if (r < 0)
    2942           0 :                 log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY: %m");
    2943           0 :         else if (r > 0) {
    2944             : 
    2945             :                 /* Non-EFI case, let's process /run/systemd/reboot-to-boot-loader-entry. */
    2946             : 
    2947           0 :                 r = read_one_line_file("/run/systemd/reboot-to-boot-loader-entry", &v);
    2948           0 :                 if (r < 0) {
    2949           0 :                         if (r != -ENOENT)
    2950           0 :                                 log_warning_errno(r, "Failed to read /run/systemd/reboot-to-boot-loader-entry: %m");
    2951           0 :                 } else if (!efi_loader_entry_name_valid(v)) {
    2952           0 :                         log_warning("/run/systemd/reboot-to-boot-loader-entry is not valid, ignoring.");
    2953           0 :                         v = mfree(v);
    2954             :                 }
    2955             :         }
    2956             : 
    2957           0 :         return sd_bus_message_append(reply, "s", v);
    2958             : }
    2959             : 
    2960           0 : static int boot_loader_entry_exists(const char *id) {
    2961           0 :         _cleanup_(boot_config_free) BootConfig config = {};
    2962             :         int r;
    2963             : 
    2964           0 :         assert(id);
    2965             : 
    2966           0 :         r = boot_entries_load_config_auto(NULL, NULL, &config);
    2967           0 :         if (r < 0 && r != -ENOKEY) /* don't complain if no GPT is found, hence skip ENOKEY */
    2968           0 :                 return r;
    2969             : 
    2970           0 :         (void) boot_entries_augment_from_loader(&config, true);
    2971             : 
    2972           0 :         return boot_config_has_entry(&config, id);
    2973             : }
    2974             : 
    2975           0 : static int method_set_reboot_to_boot_loader_entry(
    2976             :                 sd_bus_message *message,
    2977             :                 void *userdata,
    2978             :                 sd_bus_error *error) {
    2979             : 
    2980           0 :         Manager *m = userdata;
    2981             :         bool use_efi;
    2982             :         const char *v;
    2983             :         int r;
    2984             : 
    2985           0 :         assert(message);
    2986           0 :         assert(m);
    2987             : 
    2988           0 :         r = sd_bus_message_read(message, "s", &v);
    2989           0 :         if (r < 0)
    2990           0 :                 return r;
    2991             : 
    2992           0 :         if (isempty(v))
    2993           0 :                 v = NULL;
    2994           0 :         else if (efi_loader_entry_name_valid(v)) {
    2995           0 :                 r = boot_loader_entry_exists(v);
    2996           0 :                 if (r < 0)
    2997           0 :                         return r;
    2998           0 :                 if (r == 0)
    2999           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Boot loader entry '%s' is not known.", v);
    3000             :         } else
    3001           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Boot loader entry name '%s' is not valid, refusing.", v);
    3002             : 
    3003           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY");
    3004           0 :         if (r == -ENXIO) {
    3005             :                 uint64_t features;
    3006             : 
    3007             :                 /* EFI case: let's see if booting into boot loader entry is supported. */
    3008             : 
    3009           0 :                 r = efi_loader_get_features(&features);
    3010           0 :                 if (r < 0)
    3011           0 :                         log_warning_errno(r, "Failed to determine whether reboot into boot loader entry is supported: %m");
    3012           0 :                 if (r < 0 || !FLAGS_SET(features, EFI_LOADER_FEATURE_ENTRY_ONESHOT))
    3013           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Loader does not support boot into boot loader entry.");
    3014             : 
    3015           0 :                 use_efi = true;
    3016             : 
    3017           0 :         } else if (r <= 0) {
    3018             :                 /* non-EFI case: $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY is set to off */
    3019             : 
    3020           0 :                 if (r < 0)
    3021           0 :                         log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY: %m");
    3022             : 
    3023           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Loader does not support boot into boot loader entry.");
    3024             :         } else
    3025             :                 /* non-EFI case: $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY is set to on */
    3026           0 :                 use_efi = false;
    3027             : 
    3028           0 :         r = bus_verify_polkit_async(message,
    3029             :                                     CAP_SYS_ADMIN,
    3030             :                                     "org.freedesktop.login1.set-reboot-to-boot-loader-entry",
    3031             :                                     NULL,
    3032             :                                     false,
    3033             :                                     UID_INVALID,
    3034             :                                     &m->polkit_registry,
    3035             :                                     error);
    3036           0 :         if (r < 0)
    3037           0 :                 return r;
    3038           0 :         if (r == 0)
    3039           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    3040             : 
    3041           0 :         if (use_efi) {
    3042           0 :                 if (isempty(v))
    3043             :                         /* Delete item */
    3044           0 :                         r = efi_set_variable(EFI_VENDOR_LOADER, "LoaderEntryOneShot", NULL, 0);
    3045             :                 else
    3046           0 :                         r = efi_set_variable_string(EFI_VENDOR_LOADER, "LoaderEntryOneShot", v);
    3047           0 :                 if (r < 0)
    3048           0 :                         return r;
    3049             :         } else {
    3050           0 :                 if (isempty(v)) {
    3051           0 :                         if (unlink("/run/systemd/reboot-to-boot-loader-entry") < 0 && errno != ENOENT)
    3052           0 :                                 return -errno;
    3053             :                 } else {
    3054           0 :                         r = write_string_file_atomic_label("/run/systemd/reboot-boot-to-loader-entry", v);
    3055           0 :                         if (r < 0)
    3056           0 :                                 return r;
    3057             :                 }
    3058             :         }
    3059             : 
    3060           0 :         return sd_bus_reply_method_return(message, NULL);
    3061             : }
    3062             : 
    3063           0 : static int method_can_reboot_to_boot_loader_entry(
    3064             :                 sd_bus_message *message,
    3065             :                 void *userdata,
    3066             :                 sd_bus_error *error) {
    3067             : 
    3068           0 :         Manager *m = userdata;
    3069             :         int r;
    3070             : 
    3071           0 :         assert(message);
    3072           0 :         assert(m);
    3073             : 
    3074           0 :         r = getenv_bool("SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY");
    3075           0 :         if (r == -ENXIO) {
    3076           0 :                 uint64_t features = 0;
    3077             : 
    3078             :                 /* EFI case, let's see if booting into boot loader entry is supported. */
    3079             : 
    3080           0 :                 r = efi_loader_get_features(&features);
    3081           0 :                 if (r < 0)
    3082           0 :                         log_warning_errno(r, "Failed to determine whether reboot to boot loader entry is supported: %m");
    3083           0 :                 if (r < 0 || !FLAGS_SET(features, EFI_LOADER_FEATURE_ENTRY_ONESHOT))
    3084           0 :                         return sd_bus_reply_method_return(message, "s", "na");
    3085             : 
    3086           0 :         } else if (r <= 0) {
    3087             :                 /* Non-EFI case: let's trust $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY */
    3088             : 
    3089           0 :                 if (r < 0)
    3090           0 :                         log_warning_errno(r, "Failed to parse $SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY: %m");
    3091             : 
    3092           0 :                 return sd_bus_reply_method_return(message, "s", "na");
    3093             :         }
    3094             : 
    3095           0 :         return return_test_polkit(
    3096             :                         message,
    3097             :                         CAP_SYS_ADMIN,
    3098             :                         "org.freedesktop.login1.set-reboot-to-boot-loader-entry",
    3099             :                         NULL,
    3100             :                         UID_INVALID,
    3101             :                         error);
    3102             : }
    3103             : 
    3104           0 : static int property_get_boot_loader_entries(
    3105             :                 sd_bus *bus,
    3106             :                 const char *path,
    3107             :                 const char *interface,
    3108             :                 const char *property,
    3109             :                 sd_bus_message *reply,
    3110             :                 void *userdata,
    3111             :                 sd_bus_error *error) {
    3112             : 
    3113           0 :         _cleanup_(boot_config_free) BootConfig config = {};
    3114             :         size_t i;
    3115             :         int r;
    3116             : 
    3117           0 :         assert(bus);
    3118           0 :         assert(reply);
    3119           0 :         assert(userdata);
    3120             : 
    3121           0 :         r = boot_entries_load_config_auto(NULL, NULL, &config);
    3122           0 :         if (r < 0 && r != -ENOKEY) /* don't complain if there's no GPT found */
    3123           0 :                 return r;
    3124             : 
    3125           0 :         (void) boot_entries_augment_from_loader(&config, true);
    3126             : 
    3127           0 :         r = sd_bus_message_open_container(reply, 'a', "s");
    3128           0 :         if (r < 0)
    3129           0 :                 return r;
    3130             : 
    3131           0 :         for (i = 0; i < config.n_entries; i++) {
    3132           0 :                 BootEntry *e = config.entries + i;
    3133             : 
    3134           0 :                 r = sd_bus_message_append(reply, "s", e->id);
    3135           0 :                 if (r < 0)
    3136           0 :                         return r;
    3137             :         }
    3138             : 
    3139           0 :         return sd_bus_message_close_container(reply);
    3140             : }
    3141             : 
    3142           0 : static int method_set_wall_message(
    3143             :                 sd_bus_message *message,
    3144             :                 void *userdata,
    3145             :                 sd_bus_error *error) {
    3146             : 
    3147             :         int r;
    3148           0 :         Manager *m = userdata;
    3149             :         char *wall_message;
    3150             :         unsigned enable_wall_messages;
    3151             : 
    3152           0 :         assert(message);
    3153           0 :         assert(m);
    3154             : 
    3155           0 :         r = sd_bus_message_read(message, "sb", &wall_message, &enable_wall_messages);
    3156           0 :         if (r < 0)
    3157           0 :                 return r;
    3158             : 
    3159           0 :         r = bus_verify_polkit_async(message,
    3160             :                                     CAP_SYS_ADMIN,
    3161             :                                     "org.freedesktop.login1.set-wall-message",
    3162             :                                     NULL,
    3163             :                                     false,
    3164             :                                     UID_INVALID,
    3165             :                                     &m->polkit_registry,
    3166             :                                     error);
    3167           0 :         if (r < 0)
    3168           0 :                 return r;
    3169           0 :         if (r == 0)
    3170           0 :                 return 1; /* Will call us back */
    3171             : 
    3172           0 :         r = free_and_strdup(&m->wall_message, empty_to_null(wall_message));
    3173           0 :         if (r < 0)
    3174           0 :                 return log_oom();
    3175             : 
    3176           0 :         m->enable_wall_messages = enable_wall_messages;
    3177             : 
    3178           0 :         return sd_bus_reply_method_return(message, NULL);
    3179             : }
    3180             : 
    3181           0 : static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    3182           0 :         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
    3183             :         const char *who, *why, *what, *mode;
    3184           0 :         _cleanup_free_ char *id = NULL;
    3185           0 :         _cleanup_close_ int fifo_fd = -1;
    3186           0 :         Manager *m = userdata;
    3187           0 :         Inhibitor *i = NULL;
    3188             :         InhibitMode mm;
    3189             :         InhibitWhat w;
    3190             :         pid_t pid;
    3191             :         uid_t uid;
    3192             :         int r;
    3193             : 
    3194           0 :         assert(message);
    3195           0 :         assert(m);
    3196             : 
    3197           0 :         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
    3198           0 :         if (r < 0)
    3199           0 :                 return r;
    3200             : 
    3201           0 :         w = inhibit_what_from_string(what);
    3202           0 :         if (w <= 0)
    3203           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
    3204             :                                          "Invalid what specification %s", what);
    3205             : 
    3206           0 :         mm = inhibit_mode_from_string(mode);
    3207           0 :         if (mm < 0)
    3208           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
    3209             :                                          "Invalid mode specification %s", mode);
    3210             : 
    3211             :         /* Delay is only supported for shutdown/sleep */
    3212           0 :         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
    3213           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
    3214             :                                          "Delay inhibitors only supported for shutdown and sleep");
    3215             : 
    3216             :         /* Don't allow taking delay locks while we are already
    3217             :          * executing the operation. We shouldn't create the impression
    3218             :          * that the lock was successful if the machine is about to go
    3219             :          * down/suspend any moment. */
    3220           0 :         if (m->action_what & w)
    3221           0 :                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS,
    3222             :                                          "The operation inhibition has been requested for is already running");
    3223             : 
    3224           0 :         r = bus_verify_polkit_async(
    3225             :                         message,
    3226             :                         CAP_SYS_BOOT,
    3227           0 :                         w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
    3228           0 :                         w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
    3229           0 :                         w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
    3230           0 :                         w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
    3231           0 :                         w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
    3232           0 :                         w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
    3233             :                                                             "org.freedesktop.login1.inhibit-handle-lid-switch",
    3234             :                         NULL,
    3235             :                         false,
    3236             :                         UID_INVALID,
    3237             :                         &m->polkit_registry,
    3238             :                         error);
    3239           0 :         if (r < 0)
    3240           0 :                 return r;
    3241           0 :         if (r == 0)
    3242           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    3243             : 
    3244           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
    3245           0 :         if (r < 0)
    3246           0 :                 return r;
    3247             : 
    3248           0 :         r = sd_bus_creds_get_euid(creds, &uid);
    3249           0 :         if (r < 0)
    3250           0 :                 return r;
    3251             : 
    3252           0 :         r = sd_bus_creds_get_pid(creds, &pid);
    3253           0 :         if (r < 0)
    3254           0 :                 return r;
    3255             : 
    3256           0 :         if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
    3257           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED,
    3258             :                                          "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.",
    3259             :                                          m->inhibitors_max);
    3260             : 
    3261             :         do {
    3262           0 :                 id = mfree(id);
    3263             : 
    3264           0 :                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
    3265           0 :                         return -ENOMEM;
    3266             : 
    3267           0 :         } while (hashmap_get(m->inhibitors, id));
    3268             : 
    3269           0 :         r = manager_add_inhibitor(m, id, &i);
    3270           0 :         if (r < 0)
    3271           0 :                 return r;
    3272             : 
    3273           0 :         i->what = w;
    3274           0 :         i->mode = mm;
    3275           0 :         i->pid = pid;
    3276           0 :         i->uid = uid;
    3277           0 :         i->why = strdup(why);
    3278           0 :         i->who = strdup(who);
    3279             : 
    3280           0 :         if (!i->why || !i->who) {
    3281           0 :                 r = -ENOMEM;
    3282           0 :                 goto fail;
    3283             :         }
    3284             : 
    3285           0 :         fifo_fd = inhibitor_create_fifo(i);
    3286           0 :         if (fifo_fd < 0) {
    3287           0 :                 r = fifo_fd;
    3288           0 :                 goto fail;
    3289             :         }
    3290             : 
    3291           0 :         r = inhibitor_start(i);
    3292           0 :         if (r < 0)
    3293           0 :                 goto fail;
    3294             : 
    3295           0 :         return sd_bus_reply_method_return(message, "h", fifo_fd);
    3296             : 
    3297           0 : fail:
    3298           0 :         if (i)
    3299           0 :                 inhibitor_free(i);
    3300             : 
    3301           0 :         return r;
    3302             : }
    3303             : 
    3304             : const sd_bus_vtable manager_vtable[] = {
    3305             :         SD_BUS_VTABLE_START(0),
    3306             : 
    3307             :         SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
    3308             :         SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
    3309             : 
    3310             :         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
    3311             :         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
    3312             :         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
    3313             :         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
    3314             :         SD_BUS_PROPERTY("RebootParameter", "s", property_get_reboot_parameter, 0, 0),
    3315             :         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, 0),
    3316             :         SD_BUS_PROPERTY("RebootToBootLoaderMenu", "t", property_get_reboot_to_boot_loader_menu, 0, 0),
    3317             :         SD_BUS_PROPERTY("RebootToBootLoaderEntry", "s", property_get_reboot_to_boot_loader_entry, 0, 0),
    3318             :         SD_BUS_PROPERTY("BootLoaderEntries", "as", property_get_boot_loader_entries, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    3319             :         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    3320             :         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    3321             :         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    3322             :         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    3323             :         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    3324             :         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
    3325             :         SD_BUS_PROPERTY("UserStopDelayUSec", "t", NULL, offsetof(Manager, user_stop_delay), SD_BUS_VTABLE_PROPERTY_CONST),
    3326             :         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
    3327             :         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
    3328             :         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
    3329             :         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
    3330             :         SD_BUS_PROPERTY("HandleLidSwitchExternalPower", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_ep), SD_BUS_VTABLE_PROPERTY_CONST),
    3331             :         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
    3332             :         SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    3333             :         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
    3334             :         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    3335             :         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
    3336             :         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
    3337             :         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
    3338             :         SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
    3339             :         SD_BUS_PROPERTY("LidClosed", "b", property_get_lid_closed, 0, 0),
    3340             :         SD_BUS_PROPERTY("OnExternalPower", "b", property_get_on_external_power, 0, 0),
    3341             :         SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
    3342             :         SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
    3343             :         SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
    3344             :         SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_hashmap_size, offsetof(Manager, inhibitors), 0),
    3345             :         SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
    3346             :         SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_hashmap_size, offsetof(Manager, sessions), 0),
    3347             :         SD_BUS_PROPERTY("UserTasksMax", "t", property_get_compat_user_tasks_max, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
    3348             : 
    3349             :         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
    3350             :         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
    3351             :         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
    3352             :         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
    3353             :         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
    3354             :         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
    3355             :         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
    3356             :         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
    3357             :         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
    3358             :         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
    3359             :         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
    3360             :         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
    3361             :         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
    3362             :         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
    3363             :         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
    3364             :         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
    3365             :         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
    3366             :         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
    3367             :         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
    3368             :         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
    3369             :         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
    3370             :         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
    3371             :         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
    3372             :         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
    3373             :         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
    3374             :         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
    3375             :         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
    3376             :         SD_BUS_METHOD("Halt", "b", NULL, method_halt, SD_BUS_VTABLE_UNPRIVILEGED),
    3377             :         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
    3378             :         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
    3379             :         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
    3380             :         SD_BUS_METHOD("SuspendThenHibernate", "b", NULL, method_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
    3381             :         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
    3382             :         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
    3383             :         SD_BUS_METHOD("CanHalt", NULL, "s", method_can_halt, SD_BUS_VTABLE_UNPRIVILEGED),
    3384             :         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
    3385             :         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
    3386             :         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
    3387             :         SD_BUS_METHOD("CanSuspendThenHibernate", NULL, "s", method_can_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
    3388             :         SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
    3389             :         SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
    3390             :         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
    3391             :         SD_BUS_METHOD("CanRebootParameter", NULL, "s", method_can_reboot_parameter, SD_BUS_VTABLE_UNPRIVILEGED),
    3392             :         SD_BUS_METHOD("SetRebootParameter", "s", NULL, method_set_reboot_parameter, SD_BUS_VTABLE_UNPRIVILEGED),
    3393             :         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
    3394             :         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
    3395             :         SD_BUS_METHOD("CanRebootToBootLoaderMenu", NULL, "s", method_can_reboot_to_boot_loader_menu, SD_BUS_VTABLE_UNPRIVILEGED),
    3396             :         SD_BUS_METHOD("SetRebootToBootLoaderMenu", "t", NULL, method_set_reboot_to_boot_loader_menu, SD_BUS_VTABLE_UNPRIVILEGED),
    3397             :         SD_BUS_METHOD("CanRebootToBootLoaderEntry", NULL, "s", method_can_reboot_to_boot_loader_entry, SD_BUS_VTABLE_UNPRIVILEGED),
    3398             :         SD_BUS_METHOD("SetRebootToBootLoaderEntry", "s", NULL, method_set_reboot_to_boot_loader_entry, SD_BUS_VTABLE_UNPRIVILEGED),
    3399             :         SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
    3400             : 
    3401             :         SD_BUS_SIGNAL("SessionNew", "so", 0),
    3402             :         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
    3403             :         SD_BUS_SIGNAL("UserNew", "uo", 0),
    3404             :         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
    3405             :         SD_BUS_SIGNAL("SeatNew", "so", 0),
    3406             :         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
    3407             :         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
    3408             :         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
    3409             : 
    3410             :         SD_BUS_VTABLE_END
    3411             : };
    3412             : 
    3413           0 : static int session_jobs_reply(Session *s, const char *unit, const char *result) {
    3414           0 :         assert(s);
    3415           0 :         assert(unit);
    3416             : 
    3417           0 :         if (!s->started)
    3418           0 :                 return 0;
    3419             : 
    3420           0 :         if (result && !streq(result, "done")) {
    3421           0 :                 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
    3422             : 
    3423           0 :                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED,
    3424             :                                   "Start job for unit '%s' failed with '%s'", unit, result);
    3425           0 :                 return session_send_create_reply(s, &e);
    3426             :         }
    3427             : 
    3428           0 :         return session_send_create_reply(s, NULL);
    3429             : }
    3430             : 
    3431           0 : int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    3432             :         const char *path, *result, *unit;
    3433           0 :         Manager *m = userdata;
    3434             :         Session *session;
    3435             :         uint32_t id;
    3436             :         User *user;
    3437             :         int r;
    3438             : 
    3439           0 :         assert(message);
    3440           0 :         assert(m);
    3441             : 
    3442           0 :         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
    3443           0 :         if (r < 0) {
    3444           0 :                 bus_log_parse_error(r);
    3445           0 :                 return 0;
    3446             :         }
    3447             : 
    3448           0 :         if (m->action_job && streq(m->action_job, path)) {
    3449           0 :                 log_info("Operation '%s' finished.", inhibit_what_to_string(m->action_what));
    3450             : 
    3451             :                 /* Tell people that they now may take a lock again */
    3452           0 :                 (void) send_prepare_for(m, m->action_what, false);
    3453             : 
    3454           0 :                 m->action_job = mfree(m->action_job);
    3455           0 :                 m->action_unit = NULL;
    3456           0 :                 m->action_what = 0;
    3457           0 :                 return 0;
    3458             :         }
    3459             : 
    3460           0 :         session = hashmap_get(m->session_units, unit);
    3461           0 :         if (session) {
    3462           0 :                 if (streq_ptr(path, session->scope_job)) {
    3463           0 :                         session->scope_job = mfree(session->scope_job);
    3464           0 :                         (void) session_jobs_reply(session, unit, result);
    3465             : 
    3466           0 :                         session_save(session);
    3467           0 :                         user_save(session->user);
    3468             :                 }
    3469             : 
    3470           0 :                 session_add_to_gc_queue(session);
    3471             :         }
    3472             : 
    3473           0 :         user = hashmap_get(m->user_units, unit);
    3474           0 :         if (user) {
    3475           0 :                 if (streq_ptr(path, user->service_job)) {
    3476           0 :                         user->service_job = mfree(user->service_job);
    3477             : 
    3478           0 :                         LIST_FOREACH(sessions_by_user, session, user->sessions)
    3479           0 :                                 (void) session_jobs_reply(session, unit, NULL /* don't propagate user service failures to the client */);
    3480             : 
    3481           0 :                         user_save(user);
    3482             :                 }
    3483             : 
    3484           0 :                 user_add_to_gc_queue(user);
    3485             :         }
    3486             : 
    3487           0 :         return 0;
    3488             : }
    3489             : 
    3490           0 : int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    3491             :         const char *path, *unit;
    3492           0 :         Manager *m = userdata;
    3493             :         Session *session;
    3494             :         User *user;
    3495             :         int r;
    3496             : 
    3497           0 :         assert(message);
    3498           0 :         assert(m);
    3499             : 
    3500           0 :         r = sd_bus_message_read(message, "so", &unit, &path);
    3501           0 :         if (r < 0) {
    3502           0 :                 bus_log_parse_error(r);
    3503           0 :                 return 0;
    3504             :         }
    3505             : 
    3506           0 :         session = hashmap_get(m->session_units, unit);
    3507           0 :         if (session)
    3508           0 :                 session_add_to_gc_queue(session);
    3509             : 
    3510           0 :         user = hashmap_get(m->user_units, unit);
    3511           0 :         if (user)
    3512           0 :                 user_add_to_gc_queue(user);
    3513             : 
    3514           0 :         return 0;
    3515             : }
    3516             : 
    3517           0 : int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    3518           0 :         _cleanup_free_ char *unit = NULL;
    3519           0 :         Manager *m = userdata;
    3520             :         const char *path;
    3521             :         Session *session;
    3522             :         User *user;
    3523             :         int r;
    3524             : 
    3525           0 :         assert(message);
    3526           0 :         assert(m);
    3527             : 
    3528           0 :         path = sd_bus_message_get_path(message);
    3529           0 :         if (!path)
    3530           0 :                 return 0;
    3531             : 
    3532           0 :         r = unit_name_from_dbus_path(path, &unit);
    3533           0 :         if (r == -EINVAL) /* not a unit */
    3534           0 :                 return 0;
    3535           0 :         if (r < 0) {
    3536           0 :                 log_oom();
    3537           0 :                 return 0;
    3538             :         }
    3539             : 
    3540           0 :         session = hashmap_get(m->session_units, unit);
    3541           0 :         if (session)
    3542           0 :                 session_add_to_gc_queue(session);
    3543             : 
    3544           0 :         user = hashmap_get(m->user_units, unit);
    3545           0 :         if (user)
    3546           0 :                 user_add_to_gc_queue(user);
    3547             : 
    3548           0 :         return 0;
    3549             : }
    3550             : 
    3551           0 : int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    3552           0 :         Manager *m = userdata;
    3553             :         Session *session;
    3554             :         Iterator i;
    3555             :         int b, r;
    3556             : 
    3557           0 :         assert(message);
    3558           0 :         assert(m);
    3559             : 
    3560           0 :         r = sd_bus_message_read(message, "b", &b);
    3561           0 :         if (r < 0) {
    3562           0 :                 bus_log_parse_error(r);
    3563           0 :                 return 0;
    3564             :         }
    3565             : 
    3566           0 :         if (b)
    3567           0 :                 return 0;
    3568             : 
    3569             :         /* systemd finished reloading, let's recheck all our sessions */
    3570           0 :         log_debug("System manager has been reloaded, rechecking sessions...");
    3571             : 
    3572           0 :         HASHMAP_FOREACH(session, m->sessions, i)
    3573           0 :                 session_add_to_gc_queue(session);
    3574             : 
    3575           0 :         return 0;
    3576             : }
    3577             : 
    3578           0 : int manager_send_changed(Manager *manager, const char *property, ...) {
    3579             :         char **l;
    3580             : 
    3581           0 :         assert(manager);
    3582             : 
    3583           0 :         l = strv_from_stdarg_alloca(property);
    3584             : 
    3585           0 :         return sd_bus_emit_properties_changed_strv(
    3586             :                         manager->bus,
    3587             :                         "/org/freedesktop/login1",
    3588             :                         "org.freedesktop.login1.Manager",
    3589             :                         l);
    3590             : }
    3591             : 
    3592           0 : static int strdup_job(sd_bus_message *reply, char **job) {
    3593             :         const char *j;
    3594             :         char *copy;
    3595             :         int r;
    3596             : 
    3597           0 :         r = sd_bus_message_read(reply, "o", &j);
    3598           0 :         if (r < 0)
    3599           0 :                 return r;
    3600             : 
    3601           0 :         copy = strdup(j);
    3602           0 :         if (!copy)
    3603           0 :                 return -ENOMEM;
    3604             : 
    3605           0 :         *job = copy;
    3606           0 :         return 1;
    3607             : }
    3608             : 
    3609           0 : int manager_start_scope(
    3610             :                 Manager *manager,
    3611             :                 const char *scope,
    3612             :                 pid_t pid,
    3613             :                 const char *slice,
    3614             :                 const char *description,
    3615             :                 char **wants,
    3616             :                 char **after,
    3617             :                 const char *requires_mounts_for,
    3618             :                 sd_bus_message *more_properties,
    3619             :                 sd_bus_error *error,
    3620             :                 char **job) {
    3621             : 
    3622           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
    3623             :         char **i;
    3624             :         int r;
    3625             : 
    3626           0 :         assert(manager);
    3627           0 :         assert(scope);
    3628           0 :         assert(pid > 1);
    3629           0 :         assert(job);
    3630             : 
    3631           0 :         r = sd_bus_message_new_method_call(
    3632             :                         manager->bus,
    3633             :                         &m,
    3634             :                         "org.freedesktop.systemd1",
    3635             :                         "/org/freedesktop/systemd1",
    3636             :                         "org.freedesktop.systemd1.Manager",
    3637             :                         "StartTransientUnit");
    3638           0 :         if (r < 0)
    3639           0 :                 return r;
    3640             : 
    3641           0 :         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
    3642           0 :         if (r < 0)
    3643           0 :                 return r;
    3644             : 
    3645           0 :         r = sd_bus_message_open_container(m, 'a', "(sv)");
    3646           0 :         if (r < 0)
    3647           0 :                 return r;
    3648             : 
    3649           0 :         if (!isempty(slice)) {
    3650           0 :                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
    3651           0 :                 if (r < 0)
    3652           0 :                         return r;
    3653             :         }
    3654             : 
    3655           0 :         if (!isempty(description)) {
    3656           0 :                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
    3657           0 :                 if (r < 0)
    3658           0 :                         return r;
    3659             :         }
    3660             : 
    3661           0 :         STRV_FOREACH(i, wants) {
    3662           0 :                 r = sd_bus_message_append(m, "(sv)", "Wants", "as", 1, *i);
    3663           0 :                 if (r < 0)
    3664           0 :                         return r;
    3665             :         }
    3666             : 
    3667           0 :         STRV_FOREACH(i, after) {
    3668           0 :                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i);
    3669           0 :                 if (r < 0)
    3670           0 :                         return r;
    3671             :         }
    3672             : 
    3673           0 :         if (!empty_or_root(requires_mounts_for)) {
    3674           0 :                 r = sd_bus_message_append(m, "(sv)", "RequiresMountsFor", "as", 1, requires_mounts_for);
    3675           0 :                 if (r < 0)
    3676           0 :                         return r;
    3677             :         }
    3678             : 
    3679             :         /* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore
    3680             :          * SIGTERM */
    3681           0 :         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
    3682           0 :         if (r < 0)
    3683           0 :                 return r;
    3684             : 
    3685           0 :         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
    3686           0 :         if (r < 0)
    3687           0 :                 return r;
    3688             : 
    3689             :         /* disable TasksMax= for the session scope, rely on the slice setting for it */
    3690           0 :         r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", (uint64_t)-1);
    3691           0 :         if (r < 0)
    3692           0 :                 return bus_log_create_error(r);
    3693             : 
    3694           0 :         if (more_properties) {
    3695             :                 /* If TasksMax also appears here, it will overwrite the default value set above */
    3696           0 :                 r = sd_bus_message_copy(m, more_properties, true);
    3697           0 :                 if (r < 0)
    3698           0 :                         return r;
    3699             :         }
    3700             : 
    3701           0 :         r = sd_bus_message_close_container(m);
    3702           0 :         if (r < 0)
    3703           0 :                 return r;
    3704             : 
    3705           0 :         r = sd_bus_message_append(m, "a(sa(sv))", 0);
    3706           0 :         if (r < 0)
    3707           0 :                 return r;
    3708             : 
    3709           0 :         r = sd_bus_call(manager->bus, m, 0, error, &reply);
    3710           0 :         if (r < 0)
    3711           0 :                 return r;
    3712             : 
    3713           0 :         return strdup_job(reply, job);
    3714             : }
    3715             : 
    3716           0 : int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
    3717           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    3718             :         int r;
    3719             : 
    3720           0 :         assert(manager);
    3721           0 :         assert(unit);
    3722           0 :         assert(job);
    3723             : 
    3724           0 :         r = sd_bus_call_method(
    3725             :                         manager->bus,
    3726             :                         "org.freedesktop.systemd1",
    3727             :                         "/org/freedesktop/systemd1",
    3728             :                         "org.freedesktop.systemd1.Manager",
    3729             :                         "StartUnit",
    3730             :                         error,
    3731             :                         &reply,
    3732             :                         "ss", unit, "replace");
    3733           0 :         if (r < 0)
    3734           0 :                 return r;
    3735             : 
    3736           0 :         return strdup_job(reply, job);
    3737             : }
    3738             : 
    3739           0 : int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
    3740           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    3741             :         int r;
    3742             : 
    3743           0 :         assert(manager);
    3744           0 :         assert(unit);
    3745           0 :         assert(job);
    3746             : 
    3747           0 :         r = sd_bus_call_method(
    3748             :                         manager->bus,
    3749             :                         "org.freedesktop.systemd1",
    3750             :                         "/org/freedesktop/systemd1",
    3751             :                         "org.freedesktop.systemd1.Manager",
    3752             :                         "StopUnit",
    3753             :                         error,
    3754             :                         &reply,
    3755             :                         "ss", unit, "fail");
    3756           0 :         if (r < 0) {
    3757           0 :                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
    3758           0 :                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
    3759             : 
    3760           0 :                         *job = NULL;
    3761           0 :                         sd_bus_error_free(error);
    3762           0 :                         return 0;
    3763             :                 }
    3764             : 
    3765           0 :                 return r;
    3766             :         }
    3767             : 
    3768           0 :         return strdup_job(reply, job);
    3769             : }
    3770             : 
    3771           0 : int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *ret_error) {
    3772           0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    3773           0 :         _cleanup_free_ char *path = NULL;
    3774             :         int r;
    3775             : 
    3776           0 :         assert(manager);
    3777           0 :         assert(scope);
    3778             : 
    3779           0 :         path = unit_dbus_path_from_name(scope);
    3780           0 :         if (!path)
    3781           0 :                 return -ENOMEM;
    3782             : 
    3783           0 :         r = sd_bus_call_method(
    3784             :                         manager->bus,
    3785             :                         "org.freedesktop.systemd1",
    3786             :                         path,
    3787             :                         "org.freedesktop.systemd1.Scope",
    3788             :                         "Abandon",
    3789             :                         &error,
    3790             :                         NULL,
    3791             :                         NULL);
    3792           0 :         if (r < 0) {
    3793           0 :                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
    3794           0 :                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED) ||
    3795           0 :                     sd_bus_error_has_name(&error, BUS_ERROR_SCOPE_NOT_RUNNING))
    3796           0 :                         return 0;
    3797             : 
    3798           0 :                 sd_bus_error_move(ret_error, &error);
    3799           0 :                 return r;
    3800             :         }
    3801             : 
    3802           0 :         return 1;
    3803             : }
    3804             : 
    3805           0 : int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
    3806           0 :         assert(manager);
    3807           0 :         assert(unit);
    3808             : 
    3809           0 :         return sd_bus_call_method(
    3810             :                         manager->bus,
    3811             :                         "org.freedesktop.systemd1",
    3812             :                         "/org/freedesktop/systemd1",
    3813             :                         "org.freedesktop.systemd1.Manager",
    3814             :                         "KillUnit",
    3815             :                         error,
    3816             :                         NULL,
    3817             :                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
    3818             : }
    3819             : 
    3820           0 : int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *ret_error) {
    3821           0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    3822           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    3823           0 :         _cleanup_free_ char *path = NULL;
    3824             :         const char *state;
    3825             :         int r;
    3826             : 
    3827           0 :         assert(manager);
    3828           0 :         assert(unit);
    3829             : 
    3830           0 :         path = unit_dbus_path_from_name(unit);
    3831           0 :         if (!path)
    3832           0 :                 return -ENOMEM;
    3833             : 
    3834           0 :         r = sd_bus_get_property(
    3835             :                         manager->bus,
    3836             :                         "org.freedesktop.systemd1",
    3837             :                         path,
    3838             :                         "org.freedesktop.systemd1.Unit",
    3839             :                         "ActiveState",
    3840             :                         &error,
    3841             :                         &reply,
    3842             :                         "s");
    3843           0 :         if (r < 0) {
    3844             :                 /* systemd might have dropped off momentarily, let's
    3845             :                  * not make this an error */
    3846           0 :                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
    3847           0 :                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
    3848           0 :                         return true;
    3849             : 
    3850             :                 /* If the unit is already unloaded then it's not
    3851             :                  * active */
    3852           0 :                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
    3853           0 :                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
    3854           0 :                         return false;
    3855             : 
    3856           0 :                 sd_bus_error_move(ret_error, &error);
    3857           0 :                 return r;
    3858             :         }
    3859             : 
    3860           0 :         r = sd_bus_message_read(reply, "s", &state);
    3861           0 :         if (r < 0)
    3862           0 :                 return r;
    3863             : 
    3864           0 :         return !STR_IN_SET(state, "inactive", "failed");
    3865             : }
    3866             : 
    3867           0 : int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *ret_error) {
    3868           0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    3869           0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    3870             :         int r;
    3871             : 
    3872           0 :         assert(manager);
    3873           0 :         assert(path);
    3874             : 
    3875           0 :         r = sd_bus_get_property(
    3876             :                         manager->bus,
    3877             :                         "org.freedesktop.systemd1",
    3878             :                         path,
    3879             :                         "org.freedesktop.systemd1.Job",
    3880             :                         "State",
    3881             :                         &error,
    3882             :                         &reply,
    3883             :                         "s");
    3884           0 :         if (r < 0) {
    3885           0 :                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
    3886           0 :                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
    3887           0 :                         return true;
    3888             : 
    3889           0 :                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
    3890           0 :                         return false;
    3891             : 
    3892           0 :                 sd_bus_error_move(ret_error, &error);
    3893           0 :                 return r;
    3894             :         }
    3895             : 
    3896             :         /* We don't actually care about the state really. The fact
    3897             :          * that we could read the job state is enough for us */
    3898             : 
    3899           0 :         return true;
    3900             : }

Generated by: LCOV version 1.14