LCOV - code coverage report
Current view: top level - login - logind-dbus.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 0 1516 0.0 %
Date: 2015-07-29 18:47:03 Functions: 0 82 0.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2011 Lennart Poettering
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd is distributed in the hope that it will be useful, but
      14             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :   Lesser General Public License for more details.
      17             : 
      18             :   You should have received a copy of the GNU Lesser General Public License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include <errno.h>
      23             : #include <string.h>
      24             : #include <unistd.h>
      25             : #include <pwd.h>
      26             : 
      27             : #include "sd-messages.h"
      28             : #include "strv.h"
      29             : #include "mkdir.h"
      30             : #include "path-util.h"
      31             : #include "special.h"
      32             : #include "sleep-config.h"
      33             : #include "fileio-label.h"
      34             : #include "unit-name.h"
      35             : #include "audit.h"
      36             : #include "bus-util.h"
      37             : #include "bus-error.h"
      38             : #include "bus-common-errors.h"
      39             : #include "udev-util.h"
      40             : #include "selinux-util.h"
      41             : #include "efivars.h"
      42             : #include "logind.h"
      43             : #include "formats-util.h"
      44             : #include "process-util.h"
      45             : #include "terminal-util.h"
      46             : #include "utmp-wtmp.h"
      47             : 
      48           0 : int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
      49           0 :         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
      50             :         Session *session;
      51             :         int r;
      52             : 
      53           0 :         assert(m);
      54           0 :         assert(message);
      55           0 :         assert(ret);
      56             : 
      57           0 :         if (isempty(name)) {
      58           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
      59           0 :                 if (r < 0)
      60           0 :                         return r;
      61             : 
      62           0 :                 r = sd_bus_creds_get_session(creds, &name);
      63           0 :                 if (r < 0)
      64           0 :                         return r;
      65             :         }
      66             : 
      67           0 :         session = hashmap_get(m->sessions, name);
      68           0 :         if (!session)
      69           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
      70             : 
      71           0 :         *ret = session;
      72           0 :         return 0;
      73             : }
      74             : 
      75           0 : int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
      76             :         User *user;
      77             :         int r;
      78             : 
      79           0 :         assert(m);
      80           0 :         assert(message);
      81           0 :         assert(ret);
      82             : 
      83           0 :         if (uid == UID_INVALID) {
      84           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
      85             : 
      86             :                 /* Note that we get the owner UID of the session, not the actual client UID here! */
      87           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
      88           0 :                 if (r < 0)
      89           0 :                         return r;
      90             : 
      91           0 :                 r = sd_bus_creds_get_owner_uid(creds, &uid);
      92           0 :                 if (r < 0)
      93           0 :                         return r;
      94             :         }
      95             : 
      96           0 :         user = hashmap_get(m->users, UID_TO_PTR(uid));
      97           0 :         if (!user)
      98           0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
      99             : 
     100           0 :         *ret = user;
     101           0 :         return 0;
     102             : }
     103             : 
     104           0 : int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
     105             :         Seat *seat;
     106             :         int r;
     107             : 
     108           0 :         assert(m);
     109           0 :         assert(message);
     110           0 :         assert(ret);
     111             : 
     112           0 :         if (isempty(name)) {
     113             :                 Session *session;
     114             : 
     115           0 :                 r = manager_get_session_from_creds(m, message, NULL, error, &session);
     116           0 :                 if (r < 0)
     117           0 :                         return r;
     118             : 
     119           0 :                 seat = session->seat;
     120             : 
     121           0 :                 if (!seat)
     122           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
     123             :         } else {
     124           0 :                 seat = hashmap_get(m->seats, name);
     125           0 :                 if (!seat)
     126           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
     127             :         }
     128             : 
     129           0 :         *ret = seat;
     130           0 :         return 0;
     131             : }
     132             : 
     133           0 : static int property_get_idle_hint(
     134             :                 sd_bus *bus,
     135             :                 const char *path,
     136             :                 const char *interface,
     137             :                 const char *property,
     138             :                 sd_bus_message *reply,
     139             :                 void *userdata,
     140             :                 sd_bus_error *error) {
     141             : 
     142           0 :         Manager *m = userdata;
     143             : 
     144           0 :         assert(bus);
     145           0 :         assert(reply);
     146           0 :         assert(m);
     147             : 
     148           0 :         return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
     149             : }
     150             : 
     151           0 : static int property_get_idle_since_hint(
     152             :                 sd_bus *bus,
     153             :                 const char *path,
     154             :                 const char *interface,
     155             :                 const char *property,
     156             :                 sd_bus_message *reply,
     157             :                 void *userdata,
     158             :                 sd_bus_error *error) {
     159             : 
     160           0 :         Manager *m = userdata;
     161           0 :         dual_timestamp t = DUAL_TIMESTAMP_NULL;
     162             : 
     163           0 :         assert(bus);
     164           0 :         assert(reply);
     165           0 :         assert(m);
     166             : 
     167           0 :         manager_get_idle_hint(m, &t);
     168             : 
     169           0 :         return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
     170             : }
     171             : 
     172           0 : static int property_get_inhibited(
     173             :                 sd_bus *bus,
     174             :                 const char *path,
     175             :                 const char *interface,
     176             :                 const char *property,
     177             :                 sd_bus_message *reply,
     178             :                 void *userdata,
     179             :                 sd_bus_error *error) {
     180             : 
     181           0 :         Manager *m = userdata;
     182             :         InhibitWhat w;
     183             : 
     184           0 :         assert(bus);
     185           0 :         assert(reply);
     186           0 :         assert(m);
     187             : 
     188           0 :         w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
     189             : 
     190           0 :         return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
     191             : }
     192             : 
     193           0 : static int property_get_preparing(
     194             :                 sd_bus *bus,
     195             :                 const char *path,
     196             :                 const char *interface,
     197             :                 const char *property,
     198             :                 sd_bus_message *reply,
     199             :                 void *userdata,
     200             :                 sd_bus_error *error) {
     201             : 
     202           0 :         Manager *m = userdata;
     203             :         bool b;
     204             : 
     205           0 :         assert(bus);
     206           0 :         assert(reply);
     207           0 :         assert(m);
     208             : 
     209           0 :         if (streq(property, "PreparingForShutdown"))
     210           0 :                 b = !!(m->action_what & INHIBIT_SHUTDOWN);
     211             :         else
     212           0 :                 b = !!(m->action_what & INHIBIT_SLEEP);
     213             : 
     214           0 :         return sd_bus_message_append(reply, "b", b);
     215             : }
     216             : 
     217           0 : static int property_get_scheduled_shutdown(
     218             :                 sd_bus *bus,
     219             :                 const char *path,
     220             :                 const char *interface,
     221             :                 const char *property,
     222             :                 sd_bus_message *reply,
     223             :                 void *userdata,
     224             :                 sd_bus_error *error) {
     225             : 
     226           0 :         Manager *m = userdata;
     227             :         int r;
     228             : 
     229           0 :         assert(bus);
     230           0 :         assert(reply);
     231           0 :         assert(m);
     232             : 
     233           0 :         r = sd_bus_message_open_container(reply, 'r', "st");
     234           0 :         if (r < 0)
     235           0 :                 return r;
     236             : 
     237           0 :         r = sd_bus_message_append(reply, "st", m->scheduled_shutdown_type, m->scheduled_shutdown_timeout);
     238           0 :         if (r < 0)
     239           0 :                 return r;
     240             : 
     241           0 :         return sd_bus_message_close_container(reply);
     242             : }
     243             : 
     244           0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
     245             : 
     246           0 : static int property_get_docked(
     247             :                 sd_bus *bus,
     248             :                 const char *path,
     249             :                 const char *interface,
     250             :                 const char *property,
     251             :                 sd_bus_message *reply,
     252             :                 void *userdata,
     253             :                 sd_bus_error *error) {
     254             : 
     255           0 :         Manager *m = userdata;
     256             : 
     257           0 :         assert(bus);
     258           0 :         assert(reply);
     259           0 :         assert(m);
     260             : 
     261           0 :         return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
     262             : }
     263             : 
     264           0 : static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     265           0 :         _cleanup_free_ char *p = NULL;
     266           0 :         Manager *m = userdata;
     267             :         const char *name;
     268             :         Session *session;
     269             :         int r;
     270             : 
     271           0 :         assert(message);
     272           0 :         assert(m);
     273             : 
     274           0 :         r = sd_bus_message_read(message, "s", &name);
     275           0 :         if (r < 0)
     276           0 :                 return r;
     277             : 
     278           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     279           0 :         if (r < 0)
     280           0 :                 return r;
     281             : 
     282           0 :         p = session_bus_path(session);
     283           0 :         if (!p)
     284           0 :                 return -ENOMEM;
     285             : 
     286           0 :         return sd_bus_reply_method_return(message, "o", p);
     287             : }
     288             : 
     289           0 : static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     290           0 :         _cleanup_free_ char *p = NULL;
     291           0 :         Session *session = NULL;
     292           0 :         Manager *m = userdata;
     293             :         pid_t pid;
     294             :         int r;
     295             : 
     296           0 :         assert(message);
     297           0 :         assert(m);
     298             : 
     299             :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     300             : 
     301           0 :         r = sd_bus_message_read(message, "u", &pid);
     302           0 :         if (r < 0)
     303           0 :                 return r;
     304             : 
     305           0 :         if (pid <= 0) {
     306           0 :                 r = manager_get_session_from_creds(m, message, NULL, error, &session);
     307           0 :                 if (r < 0)
     308           0 :                         return r;
     309             :         } else {
     310           0 :                 r = manager_get_session_by_pid(m, pid, &session);
     311           0 :                 if (r < 0)
     312           0 :                         return r;
     313             : 
     314           0 :                 if (!session)
     315           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
     316             :         }
     317             : 
     318           0 :         p = session_bus_path(session);
     319           0 :         if (!p)
     320           0 :                 return -ENOMEM;
     321             : 
     322           0 :         return sd_bus_reply_method_return(message, "o", p);
     323             : }
     324             : 
     325           0 : static int method_get_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     326           0 :         _cleanup_free_ char *p = NULL;
     327           0 :         Manager *m = userdata;
     328             :         uint32_t uid;
     329             :         User *user;
     330             :         int r;
     331             : 
     332           0 :         assert(message);
     333           0 :         assert(m);
     334             : 
     335           0 :         r = sd_bus_message_read(message, "u", &uid);
     336           0 :         if (r < 0)
     337           0 :                 return r;
     338             : 
     339           0 :         r = manager_get_user_from_creds(m, message, uid, error, &user);
     340           0 :         if (r < 0)
     341           0 :                 return r;
     342             : 
     343           0 :         p = user_bus_path(user);
     344           0 :         if (!p)
     345           0 :                 return -ENOMEM;
     346             : 
     347           0 :         return sd_bus_reply_method_return(message, "o", p);
     348             : }
     349             : 
     350           0 : static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     351           0 :         _cleanup_free_ char *p = NULL;
     352           0 :         Manager *m = userdata;
     353           0 :         User *user = NULL;
     354             :         pid_t pid;
     355             :         int r;
     356             : 
     357           0 :         assert(message);
     358           0 :         assert(m);
     359             : 
     360             :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     361             : 
     362           0 :         r = sd_bus_message_read(message, "u", &pid);
     363           0 :         if (r < 0)
     364           0 :                 return r;
     365             : 
     366           0 :         if (pid <= 0) {
     367           0 :                 r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
     368           0 :                 if (r < 0)
     369           0 :                         return r;
     370             :         } else {
     371           0 :                 r = manager_get_user_by_pid(m, pid, &user);
     372           0 :                 if (r < 0)
     373           0 :                         return r;
     374           0 :                 if (!user)
     375           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
     376             :         }
     377             : 
     378           0 :         p = user_bus_path(user);
     379           0 :         if (!p)
     380           0 :                 return -ENOMEM;
     381             : 
     382           0 :         return sd_bus_reply_method_return(message, "o", p);
     383             : }
     384             : 
     385           0 : static int method_get_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     386           0 :         _cleanup_free_ char *p = NULL;
     387           0 :         Manager *m = userdata;
     388             :         const char *name;
     389             :         Seat *seat;
     390             :         int r;
     391             : 
     392           0 :         assert(message);
     393           0 :         assert(m);
     394             : 
     395           0 :         r = sd_bus_message_read(message, "s", &name);
     396           0 :         if (r < 0)
     397           0 :                 return r;
     398             : 
     399           0 :         r = manager_get_seat_from_creds(m, message, name, error, &seat);
     400           0 :         if (r < 0)
     401           0 :                 return r;
     402             : 
     403           0 :         p = seat_bus_path(seat);
     404           0 :         if (!p)
     405           0 :                 return -ENOMEM;
     406             : 
     407           0 :         return sd_bus_reply_method_return(message, "o", p);
     408             : }
     409             : 
     410           0 : static int method_list_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     411           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
     412           0 :         Manager *m = userdata;
     413             :         Session *session;
     414             :         Iterator i;
     415             :         int r;
     416             : 
     417           0 :         assert(message);
     418           0 :         assert(m);
     419             : 
     420           0 :         r = sd_bus_message_new_method_return(message, &reply);
     421           0 :         if (r < 0)
     422           0 :                 return r;
     423             : 
     424           0 :         r = sd_bus_message_open_container(reply, 'a', "(susso)");
     425           0 :         if (r < 0)
     426           0 :                 return r;
     427             : 
     428           0 :         HASHMAP_FOREACH(session, m->sessions, i) {
     429           0 :                 _cleanup_free_ char *p = NULL;
     430             : 
     431           0 :                 p = session_bus_path(session);
     432           0 :                 if (!p)
     433           0 :                         return -ENOMEM;
     434             : 
     435           0 :                 r = sd_bus_message_append(reply, "(susso)",
     436           0 :                                           session->id,
     437           0 :                                           (uint32_t) session->user->uid,
     438           0 :                                           session->user->name,
     439           0 :                                           session->seat ? session->seat->id : "",
     440             :                                           p);
     441           0 :                 if (r < 0)
     442           0 :                         return r;
     443             :         }
     444             : 
     445           0 :         r = sd_bus_message_close_container(reply);
     446           0 :         if (r < 0)
     447           0 :                 return r;
     448             : 
     449           0 :         return sd_bus_send(NULL, reply, NULL);
     450             : }
     451             : 
     452           0 : static int method_list_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     453           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
     454           0 :         Manager *m = userdata;
     455             :         User *user;
     456             :         Iterator i;
     457             :         int r;
     458             : 
     459           0 :         assert(message);
     460           0 :         assert(m);
     461             : 
     462           0 :         r = sd_bus_message_new_method_return(message, &reply);
     463           0 :         if (r < 0)
     464           0 :                 return r;
     465             : 
     466           0 :         r = sd_bus_message_open_container(reply, 'a', "(uso)");
     467           0 :         if (r < 0)
     468           0 :                 return r;
     469             : 
     470           0 :         HASHMAP_FOREACH(user, m->users, i) {
     471           0 :                 _cleanup_free_ char *p = NULL;
     472             : 
     473           0 :                 p = user_bus_path(user);
     474           0 :                 if (!p)
     475           0 :                         return -ENOMEM;
     476             : 
     477           0 :                 r = sd_bus_message_append(reply, "(uso)",
     478           0 :                                           (uint32_t) user->uid,
     479           0 :                                           user->name,
     480             :                                           p);
     481           0 :                 if (r < 0)
     482           0 :                         return r;
     483             :         }
     484             : 
     485           0 :         r = sd_bus_message_close_container(reply);
     486           0 :         if (r < 0)
     487           0 :                 return r;
     488             : 
     489           0 :         return sd_bus_send(NULL, reply, NULL);
     490             : }
     491             : 
     492           0 : static int method_list_seats(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     493           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
     494           0 :         Manager *m = userdata;
     495             :         Seat *seat;
     496             :         Iterator i;
     497             :         int r;
     498             : 
     499           0 :         assert(message);
     500           0 :         assert(m);
     501             : 
     502           0 :         r = sd_bus_message_new_method_return(message, &reply);
     503           0 :         if (r < 0)
     504           0 :                 return r;
     505             : 
     506           0 :         r = sd_bus_message_open_container(reply, 'a', "(so)");
     507           0 :         if (r < 0)
     508           0 :                 return r;
     509             : 
     510           0 :         HASHMAP_FOREACH(seat, m->seats, i) {
     511           0 :                 _cleanup_free_ char *p = NULL;
     512             : 
     513           0 :                 p = seat_bus_path(seat);
     514           0 :                 if (!p)
     515           0 :                         return -ENOMEM;
     516             : 
     517           0 :                 r = sd_bus_message_append(reply, "(so)", seat->id, p);
     518           0 :                 if (r < 0)
     519           0 :                         return r;
     520             :         }
     521             : 
     522           0 :         r = sd_bus_message_close_container(reply);
     523           0 :         if (r < 0)
     524           0 :                 return r;
     525             : 
     526           0 :         return sd_bus_send(NULL, reply, NULL);
     527             : }
     528             : 
     529           0 : static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     530           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
     531           0 :         Manager *m = userdata;
     532             :         Inhibitor *inhibitor;
     533             :         Iterator i;
     534             :         int r;
     535             : 
     536           0 :         assert(message);
     537           0 :         assert(m);
     538             : 
     539           0 :         r = sd_bus_message_new_method_return(message, &reply);
     540           0 :         if (r < 0)
     541           0 :                 return r;
     542             : 
     543           0 :         r = sd_bus_message_open_container(reply, 'a', "(ssssuu)");
     544           0 :         if (r < 0)
     545           0 :                 return r;
     546             : 
     547           0 :         HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
     548             : 
     549           0 :                 r = sd_bus_message_append(reply, "(ssssuu)",
     550           0 :                                           strempty(inhibit_what_to_string(inhibitor->what)),
     551           0 :                                           strempty(inhibitor->who),
     552           0 :                                           strempty(inhibitor->why),
     553           0 :                                           strempty(inhibit_mode_to_string(inhibitor->mode)),
     554           0 :                                           (uint32_t) inhibitor->uid,
     555           0 :                                           (uint32_t) inhibitor->pid);
     556           0 :                 if (r < 0)
     557           0 :                         return r;
     558             :         }
     559             : 
     560           0 :         r = sd_bus_message_close_container(reply);
     561           0 :         if (r < 0)
     562           0 :                 return r;
     563             : 
     564           0 :         return sd_bus_send(NULL, reply, NULL);
     565             : }
     566             : 
     567           0 : static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     568             :         const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
     569           0 :         uint32_t uid, leader, audit_id = 0;
     570           0 :         _cleanup_free_ char *id = NULL;
     571           0 :         Session *session = NULL;
     572           0 :         Manager *m = userdata;
     573           0 :         User *user = NULL;
     574           0 :         Seat *seat = NULL;
     575             :         int remote;
     576           0 :         uint32_t vtnr = 0;
     577             :         SessionType t;
     578             :         SessionClass c;
     579             :         int r;
     580             : 
     581           0 :         assert(message);
     582           0 :         assert(m);
     583             : 
     584           0 :         r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
     585           0 :         if (r < 0)
     586           0 :                 return r;
     587             : 
     588           0 :         if (leader == 1)
     589           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
     590             : 
     591           0 :         if (isempty(type))
     592           0 :                 t = _SESSION_TYPE_INVALID;
     593             :         else {
     594           0 :                 t = session_type_from_string(type);
     595           0 :                 if (t < 0)
     596           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session type %s", type);
     597             :         }
     598             : 
     599           0 :         if (isempty(class))
     600           0 :                 c = _SESSION_CLASS_INVALID;
     601             :         else {
     602           0 :                 c = session_class_from_string(class);
     603           0 :                 if (c < 0)
     604           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid session class %s", class);
     605             :         }
     606             : 
     607           0 :         if (isempty(desktop))
     608           0 :                 desktop = NULL;
     609             :         else {
     610           0 :                 if (!string_is_safe(desktop))
     611           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid desktop string %s", desktop);
     612             :         }
     613             : 
     614           0 :         if (isempty(cseat))
     615           0 :                 seat = NULL;
     616             :         else {
     617           0 :                 seat = hashmap_get(m->seats, cseat);
     618           0 :                 if (!seat)
     619           0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", cseat);
     620             :         }
     621             : 
     622           0 :         if (tty_is_vc(tty)) {
     623             :                 int v;
     624             : 
     625           0 :                 if (!seat)
     626           0 :                         seat = m->seat0;
     627           0 :                 else if (seat != m->seat0)
     628           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
     629             : 
     630           0 :                 v = vtnr_from_tty(tty);
     631           0 :                 if (v <= 0)
     632           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
     633             : 
     634           0 :                 if (!vtnr)
     635           0 :                         vtnr = (uint32_t) v;
     636           0 :                 else if (vtnr != (uint32_t) v)
     637           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
     638             : 
     639           0 :         } else if (tty_is_console(tty)) {
     640             : 
     641           0 :                 if (!seat)
     642           0 :                         seat = m->seat0;
     643           0 :                 else if (seat != m->seat0)
     644           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
     645             : 
     646           0 :                 if (vtnr != 0)
     647           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
     648             :         }
     649             : 
     650           0 :         if (seat) {
     651           0 :                 if (seat_has_vts(seat)) {
     652           0 :                         if (!vtnr || vtnr > 63)
     653           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range");
     654             :                 } else {
     655           0 :                         if (vtnr != 0)
     656           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat has no VTs but VT number not 0");
     657             :                 }
     658             :         }
     659             : 
     660           0 :         r = sd_bus_message_enter_container(message, 'a', "(sv)");
     661           0 :         if (r < 0)
     662           0 :                 return r;
     663             : 
     664           0 :         if (t == _SESSION_TYPE_INVALID) {
     665           0 :                 if (!isempty(display))
     666           0 :                         t = SESSION_X11;
     667           0 :                 else if (!isempty(tty))
     668           0 :                         t = SESSION_TTY;
     669             :                 else
     670           0 :                         t = SESSION_UNSPECIFIED;
     671             :         }
     672             : 
     673           0 :         if (c == _SESSION_CLASS_INVALID) {
     674           0 :                 if (t == SESSION_UNSPECIFIED)
     675           0 :                         c = SESSION_BACKGROUND;
     676             :                 else
     677           0 :                         c = SESSION_USER;
     678             :         }
     679             : 
     680           0 :         if (leader <= 0) {
     681           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
     682             : 
     683           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     684           0 :                 if (r < 0)
     685           0 :                         return r;
     686             : 
     687           0 :                 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
     688           0 :                 if (r < 0)
     689           0 :                         return r;
     690             :         }
     691             : 
     692           0 :         r = manager_get_session_by_pid(m, leader, NULL);
     693           0 :         if (r > 0)
     694           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
     695             : 
     696             :         /*
     697             :          * Old gdm and lightdm start the user-session on the same VT as
     698             :          * the greeter session. But they destroy the greeter session
     699             :          * after the user-session and want the user-session to take
     700             :          * over the VT. We need to support this for
     701             :          * backwards-compatibility, so make sure we allow new sessions
     702             :          * on a VT that a greeter is running on. Furthermore, to allow
     703             :          * re-logins, we have to allow a greeter to take over a used VT for
     704             :          * the exact same reasons.
     705             :          */
     706           0 :         if (c != SESSION_GREETER &&
     707           0 :             vtnr > 0 &&
     708           0 :             vtnr < m->seat0->position_count &&
     709           0 :             m->seat0->positions[vtnr] &&
     710           0 :             m->seat0->positions[vtnr]->class != SESSION_GREETER)
     711           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
     712             : 
     713           0 :         audit_session_from_pid(leader, &audit_id);
     714           0 :         if (audit_id > 0) {
     715             :                 /* Keep our session IDs and the audit session IDs in sync */
     716             : 
     717           0 :                 if (asprintf(&id, "%"PRIu32, audit_id) < 0)
     718           0 :                         return -ENOMEM;
     719             : 
     720             :                 /* Wut? There's already a session by this name and we
     721             :                  * didn't find it above? Weird, then let's not trust
     722             :                  * the audit data and let's better register a new
     723             :                  * ID */
     724           0 :                 if (hashmap_get(m->sessions, id)) {
     725           0 :                         log_warning("Existing logind session ID %s used by new audit session, ignoring", id);
     726           0 :                         audit_id = 0;
     727             : 
     728           0 :                         free(id);
     729           0 :                         id = NULL;
     730             :                 }
     731             :         }
     732             : 
     733           0 :         if (!id) {
     734             :                 do {
     735           0 :                         free(id);
     736           0 :                         id = NULL;
     737             : 
     738           0 :                         if (asprintf(&id, "c%lu", ++m->session_counter) < 0)
     739           0 :                                 return -ENOMEM;
     740             : 
     741           0 :                 } while (hashmap_get(m->sessions, id));
     742             :         }
     743             : 
     744           0 :         r = manager_add_user_by_uid(m, uid, &user);
     745           0 :         if (r < 0)
     746           0 :                 goto fail;
     747             : 
     748           0 :         r = manager_add_session(m, id, &session);
     749           0 :         if (r < 0)
     750           0 :                 goto fail;
     751             : 
     752           0 :         session_set_user(session, user);
     753             : 
     754           0 :         session->leader = leader;
     755           0 :         session->audit_id = audit_id;
     756           0 :         session->type = t;
     757           0 :         session->class = c;
     758           0 :         session->remote = remote;
     759           0 :         session->vtnr = vtnr;
     760             : 
     761           0 :         if (!isempty(tty)) {
     762           0 :                 session->tty = strdup(tty);
     763           0 :                 if (!session->tty) {
     764           0 :                         r = -ENOMEM;
     765           0 :                         goto fail;
     766             :                 }
     767             :         }
     768             : 
     769           0 :         if (!isempty(display)) {
     770           0 :                 session->display = strdup(display);
     771           0 :                 if (!session->display) {
     772           0 :                         r = -ENOMEM;
     773           0 :                         goto fail;
     774             :                 }
     775             :         }
     776             : 
     777           0 :         if (!isempty(remote_user)) {
     778           0 :                 session->remote_user = strdup(remote_user);
     779           0 :                 if (!session->remote_user) {
     780           0 :                         r = -ENOMEM;
     781           0 :                         goto fail;
     782             :                 }
     783             :         }
     784             : 
     785           0 :         if (!isempty(remote_host)) {
     786           0 :                 session->remote_host = strdup(remote_host);
     787           0 :                 if (!session->remote_host) {
     788           0 :                         r = -ENOMEM;
     789           0 :                         goto fail;
     790             :                 }
     791             :         }
     792             : 
     793           0 :         if (!isempty(service)) {
     794           0 :                 session->service = strdup(service);
     795           0 :                 if (!session->service) {
     796           0 :                         r = -ENOMEM;
     797           0 :                         goto fail;
     798             :                 }
     799             :         }
     800             : 
     801           0 :         if (!isempty(desktop)) {
     802           0 :                 session->desktop = strdup(desktop);
     803           0 :                 if (!session->desktop) {
     804           0 :                         r = -ENOMEM;
     805           0 :                         goto fail;
     806             :                 }
     807             :         }
     808             : 
     809           0 :         if (seat) {
     810           0 :                 r = seat_attach_session(seat, session);
     811           0 :                 if (r < 0)
     812           0 :                         goto fail;
     813             :         }
     814             : 
     815           0 :         r = session_start(session);
     816           0 :         if (r < 0)
     817           0 :                 goto fail;
     818             : 
     819           0 :         session->create_message = sd_bus_message_ref(message);
     820             : 
     821             :         /* Now, let's wait until the slice unit and stuff got
     822             :          * created. We send the reply back from
     823             :          * session_send_create_reply(). */
     824             : 
     825           0 :         return 1;
     826             : 
     827             : fail:
     828           0 :         if (session)
     829           0 :                 session_add_to_gc_queue(session);
     830             : 
     831           0 :         if (user)
     832           0 :                 user_add_to_gc_queue(user);
     833             : 
     834           0 :         return r;
     835             : }
     836             : 
     837           0 : static int method_release_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     838           0 :         Manager *m = userdata;
     839             :         Session *session;
     840             :         const char *name;
     841             :         int r;
     842             : 
     843           0 :         assert(message);
     844           0 :         assert(m);
     845             : 
     846           0 :         r = sd_bus_message_read(message, "s", &name);
     847           0 :         if (r < 0)
     848           0 :                 return r;
     849             : 
     850           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     851           0 :         if (r < 0)
     852           0 :                 return r;
     853             : 
     854           0 :         r = session_release(session);
     855           0 :         if (r < 0)
     856           0 :                 return r;
     857             : 
     858           0 :         return sd_bus_reply_method_return(message, NULL);
     859             : }
     860             : 
     861           0 : static int method_activate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     862           0 :         Manager *m = userdata;
     863             :         Session *session;
     864             :         const char *name;
     865             :         int r;
     866             : 
     867           0 :         assert(message);
     868           0 :         assert(m);
     869             : 
     870           0 :         r = sd_bus_message_read(message, "s", &name);
     871           0 :         if (r < 0)
     872           0 :                 return r;
     873             : 
     874           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     875           0 :         if (r < 0)
     876           0 :                 return r;
     877             : 
     878           0 :         return bus_session_method_activate(message, session, error);
     879             : }
     880             : 
     881           0 : static int method_activate_session_on_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     882             :         const char *session_name, *seat_name;
     883           0 :         Manager *m = userdata;
     884             :         Session *session;
     885             :         Seat *seat;
     886             :         int r;
     887             : 
     888           0 :         assert(message);
     889           0 :         assert(m);
     890             : 
     891             :         /* Same as ActivateSession() but refuses to work if
     892             :          * the seat doesn't match */
     893             : 
     894           0 :         r = sd_bus_message_read(message, "ss", &session_name, &seat_name);
     895           0 :         if (r < 0)
     896           0 :                 return r;
     897             : 
     898           0 :         r = manager_get_session_from_creds(m, message, session_name, error, &session);
     899           0 :         if (r < 0)
     900           0 :                 return r;
     901             : 
     902           0 :         r = manager_get_seat_from_creds(m, message, seat_name, error, &seat);
     903           0 :         if (r < 0)
     904           0 :                 return r;
     905             : 
     906           0 :         if (session->seat != seat)
     907           0 :                 return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
     908             : 
     909           0 :         r = session_activate(session);
     910           0 :         if (r < 0)
     911           0 :                 return r;
     912             : 
     913           0 :         return sd_bus_reply_method_return(message, NULL);
     914             : }
     915             : 
     916           0 : static int method_lock_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     917           0 :         Manager *m = userdata;
     918             :         Session *session;
     919             :         const char *name;
     920             :         int r;
     921             : 
     922           0 :         assert(message);
     923           0 :         assert(m);
     924             : 
     925           0 :         r = sd_bus_message_read(message, "s", &name);
     926           0 :         if (r < 0)
     927           0 :                 return r;
     928             : 
     929           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     930           0 :         if (r < 0)
     931           0 :                 return r;
     932             : 
     933           0 :         return bus_session_method_lock(message, session, error);
     934             : }
     935             : 
     936           0 : static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     937           0 :         Manager *m = userdata;
     938             :         int r;
     939             : 
     940           0 :         assert(message);
     941           0 :         assert(m);
     942             : 
     943           0 :         r = bus_verify_polkit_async(
     944             :                         message,
     945             :                         CAP_SYS_ADMIN,
     946             :                         "org.freedesktop.login1.lock-sessions",
     947             :                         false,
     948             :                         UID_INVALID,
     949             :                         &m->polkit_registry,
     950             :                         error);
     951           0 :         if (r < 0)
     952           0 :                 return r;
     953           0 :         if (r == 0)
     954           0 :                 return 1; /* Will call us back */
     955             : 
     956           0 :         r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions"));
     957           0 :         if (r < 0)
     958           0 :                 return r;
     959             : 
     960           0 :         return sd_bus_reply_method_return(message, NULL);
     961             : }
     962             : 
     963           0 : static int method_kill_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     964             :         const char *name;
     965           0 :         Manager *m = userdata;
     966             :         Session *session;
     967             :         int r;
     968             : 
     969           0 :         assert(message);
     970           0 :         assert(m);
     971             : 
     972           0 :         r = sd_bus_message_read(message, "s", &name);
     973           0 :         if (r < 0)
     974           0 :                 return r;
     975             : 
     976           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
     977           0 :         if (r < 0)
     978           0 :                 return r;
     979             : 
     980           0 :         return bus_session_method_kill(message, session, error);
     981             : }
     982             : 
     983           0 : static int method_kill_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     984           0 :         Manager *m = userdata;
     985             :         uint32_t uid;
     986             :         User *user;
     987             :         int r;
     988             : 
     989           0 :         assert(message);
     990           0 :         assert(m);
     991             : 
     992           0 :         r = sd_bus_message_read(message, "u", &uid);
     993           0 :         if (r < 0)
     994           0 :                 return r;
     995             : 
     996           0 :         r = manager_get_user_from_creds(m, message, uid, error, &user);
     997           0 :         if (r < 0)
     998           0 :                 return r;
     999             : 
    1000           0 :         return bus_user_method_kill(message, user, error);
    1001             : }
    1002             : 
    1003           0 : static int method_terminate_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1004           0 :         Manager *m = userdata;
    1005             :         const char *name;
    1006             :         Session *session;
    1007             :         int r;
    1008             : 
    1009           0 :         assert(message);
    1010           0 :         assert(m);
    1011             : 
    1012           0 :         r = sd_bus_message_read(message, "s", &name);
    1013           0 :         if (r < 0)
    1014           0 :                 return r;
    1015             : 
    1016           0 :         r = manager_get_session_from_creds(m, message, name, error, &session);
    1017           0 :         if (r < 0)
    1018           0 :                 return r;
    1019             : 
    1020           0 :         return bus_session_method_terminate(message, session, error);
    1021             : }
    1022             : 
    1023           0 : static int method_terminate_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1024           0 :         Manager *m = userdata;
    1025             :         uint32_t uid;
    1026             :         User *user;
    1027             :         int r;
    1028             : 
    1029           0 :         assert(message);
    1030           0 :         assert(m);
    1031             : 
    1032           0 :         r = sd_bus_message_read(message, "u", &uid);
    1033           0 :         if (r < 0)
    1034           0 :                 return r;
    1035             : 
    1036           0 :         r = manager_get_user_from_creds(m, message, uid, error, &user);
    1037           0 :         if (r < 0)
    1038           0 :                 return r;
    1039             : 
    1040           0 :         return bus_user_method_terminate(message, user, error);
    1041             : }
    1042             : 
    1043           0 : static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1044           0 :         Manager *m = userdata;
    1045             :         const char *name;
    1046             :         Seat *seat;
    1047             :         int r;
    1048             : 
    1049           0 :         assert(message);
    1050           0 :         assert(m);
    1051             : 
    1052           0 :         r = sd_bus_message_read(message, "s", &name);
    1053           0 :         if (r < 0)
    1054           0 :                 return r;
    1055             : 
    1056           0 :         r = manager_get_seat_from_creds(m, message, name, error, &seat);
    1057           0 :         if (r < 0)
    1058           0 :                 return r;
    1059             : 
    1060           0 :         return bus_seat_method_terminate(message, seat, error);
    1061             : }
    1062             : 
    1063           0 : static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1064           0 :         _cleanup_free_ char *cc = NULL;
    1065           0 :         Manager *m = userdata;
    1066             :         int b, r;
    1067             :         struct passwd *pw;
    1068             :         const char *path;
    1069             :         uint32_t uid;
    1070             :         int interactive;
    1071             : 
    1072           0 :         assert(message);
    1073           0 :         assert(m);
    1074             : 
    1075           0 :         r = sd_bus_message_read(message, "ubb", &uid, &b, &interactive);
    1076           0 :         if (r < 0)
    1077           0 :                 return r;
    1078             : 
    1079           0 :         if (uid == UID_INVALID) {
    1080           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
    1081             : 
    1082             :                 /* Note that we get the owner UID of the session, not the actual client UID here! */
    1083           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
    1084           0 :                 if (r < 0)
    1085           0 :                         return r;
    1086             : 
    1087           0 :                 r = sd_bus_creds_get_owner_uid(creds, &uid);
    1088           0 :                 if (r < 0)
    1089           0 :                         return r;
    1090             :         }
    1091             : 
    1092           0 :         errno = 0;
    1093           0 :         pw = getpwuid(uid);
    1094           0 :         if (!pw)
    1095           0 :                 return errno ? -errno : -ENOENT;
    1096             : 
    1097           0 :         r = bus_verify_polkit_async(
    1098             :                         message,
    1099             :                         CAP_SYS_ADMIN,
    1100             :                         "org.freedesktop.login1.set-user-linger",
    1101             :                         interactive,
    1102             :                         UID_INVALID,
    1103             :                         &m->polkit_registry,
    1104             :                         error);
    1105           0 :         if (r < 0)
    1106           0 :                 return r;
    1107           0 :         if (r == 0)
    1108           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1109             : 
    1110           0 :         mkdir_p_label("/var/lib/systemd", 0755);
    1111             : 
    1112           0 :         r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
    1113           0 :         if (r < 0)
    1114           0 :                 return r;
    1115             : 
    1116           0 :         cc = cescape(pw->pw_name);
    1117           0 :         if (!cc)
    1118           0 :                 return -ENOMEM;
    1119             : 
    1120           0 :         path = strjoina("/var/lib/systemd/linger/", cc);
    1121           0 :         if (b) {
    1122             :                 User *u;
    1123             : 
    1124           0 :                 r = touch(path);
    1125           0 :                 if (r < 0)
    1126           0 :                         return r;
    1127             : 
    1128           0 :                 if (manager_add_user_by_uid(m, uid, &u) >= 0)
    1129           0 :                         user_start(u);
    1130             : 
    1131             :         } else {
    1132             :                 User *u;
    1133             : 
    1134           0 :                 r = unlink(path);
    1135           0 :                 if (r < 0 && errno != ENOENT)
    1136           0 :                         return -errno;
    1137             : 
    1138           0 :                 u = hashmap_get(m->users, UID_TO_PTR(uid));
    1139           0 :                 if (u)
    1140           0 :                         user_add_to_gc_queue(u);
    1141             :         }
    1142             : 
    1143           0 :         return sd_bus_reply_method_return(message, NULL);
    1144             : }
    1145             : 
    1146           0 : static int trigger_device(Manager *m, struct udev_device *d) {
    1147           0 :         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
    1148             :         struct udev_list_entry *first, *item;
    1149             :         int r;
    1150             : 
    1151           0 :         assert(m);
    1152             : 
    1153           0 :         e = udev_enumerate_new(m->udev);
    1154           0 :         if (!e)
    1155           0 :                 return -ENOMEM;
    1156             : 
    1157           0 :         if (d) {
    1158           0 :                 r = udev_enumerate_add_match_parent(e, d);
    1159           0 :                 if (r < 0)
    1160           0 :                         return r;
    1161             :         }
    1162             : 
    1163           0 :         r = udev_enumerate_scan_devices(e);
    1164           0 :         if (r < 0)
    1165           0 :                 return r;
    1166             : 
    1167           0 :         first = udev_enumerate_get_list_entry(e);
    1168           0 :         udev_list_entry_foreach(item, first) {
    1169           0 :                 _cleanup_free_ char *t = NULL;
    1170             :                 const char *p;
    1171             : 
    1172           0 :                 p = udev_list_entry_get_name(item);
    1173             : 
    1174           0 :                 t = strappend(p, "/uevent");
    1175           0 :                 if (!t)
    1176           0 :                         return -ENOMEM;
    1177             : 
    1178           0 :                 write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
    1179             :         }
    1180             : 
    1181           0 :         return 0;
    1182             : }
    1183             : 
    1184           0 : static int attach_device(Manager *m, const char *seat, const char *sysfs) {
    1185           0 :         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
    1186           0 :         _cleanup_free_ char *rule = NULL, *file = NULL;
    1187             :         const char *id_for_seat;
    1188             :         int r;
    1189             : 
    1190           0 :         assert(m);
    1191           0 :         assert(seat);
    1192           0 :         assert(sysfs);
    1193             : 
    1194           0 :         d = udev_device_new_from_syspath(m->udev, sysfs);
    1195           0 :         if (!d)
    1196           0 :                 return -ENODEV;
    1197             : 
    1198           0 :         if (!udev_device_has_tag(d, "seat"))
    1199           0 :                 return -ENODEV;
    1200             : 
    1201           0 :         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
    1202           0 :         if (!id_for_seat)
    1203           0 :                 return -ENODEV;
    1204             : 
    1205           0 :         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
    1206           0 :                 return -ENOMEM;
    1207             : 
    1208           0 :         if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
    1209           0 :                 return -ENOMEM;
    1210             : 
    1211           0 :         mkdir_p_label("/etc/udev/rules.d", 0755);
    1212           0 :         mac_selinux_init("/etc");
    1213           0 :         r = write_string_file_atomic_label(file, rule);
    1214           0 :         if (r < 0)
    1215           0 :                 return r;
    1216             : 
    1217           0 :         return trigger_device(m, d);
    1218             : }
    1219             : 
    1220           0 : static int flush_devices(Manager *m) {
    1221           0 :         _cleanup_closedir_ DIR *d;
    1222             : 
    1223           0 :         assert(m);
    1224             : 
    1225           0 :         d = opendir("/etc/udev/rules.d");
    1226           0 :         if (!d) {
    1227           0 :                 if (errno != ENOENT)
    1228           0 :                         log_warning_errno(errno, "Failed to open /etc/udev/rules.d: %m");
    1229             :         } else {
    1230             :                 struct dirent *de;
    1231             : 
    1232           0 :                 while ((de = readdir(d))) {
    1233             : 
    1234           0 :                         if (!dirent_is_file(de))
    1235           0 :                                 continue;
    1236             : 
    1237           0 :                         if (!startswith(de->d_name, "72-seat-"))
    1238           0 :                                 continue;
    1239             : 
    1240           0 :                         if (!endswith(de->d_name, ".rules"))
    1241           0 :                                 continue;
    1242             : 
    1243           0 :                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
    1244           0 :                                 log_warning_errno(errno, "Failed to unlink %s: %m", de->d_name);
    1245             :                 }
    1246             :         }
    1247             : 
    1248           0 :         return trigger_device(m, NULL);
    1249             : }
    1250             : 
    1251           0 : static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1252             :         const char *sysfs, *seat;
    1253           0 :         Manager *m = userdata;
    1254             :         int interactive, r;
    1255             : 
    1256           0 :         assert(message);
    1257           0 :         assert(m);
    1258             : 
    1259           0 :         r = sd_bus_message_read(message, "ssb", &seat, &sysfs, &interactive);
    1260           0 :         if (r < 0)
    1261           0 :                 return r;
    1262             : 
    1263           0 :         if (!path_startswith(sysfs, "/sys"))
    1264           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not in /sys", sysfs);
    1265             : 
    1266           0 :         if (!seat_name_is_valid(seat))
    1267           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
    1268             : 
    1269           0 :         r = bus_verify_polkit_async(
    1270             :                         message,
    1271             :                         CAP_SYS_ADMIN,
    1272             :                         "org.freedesktop.login1.attach-device",
    1273             :                         interactive,
    1274             :                         UID_INVALID,
    1275             :                         &m->polkit_registry,
    1276             :                         error);
    1277           0 :         if (r < 0)
    1278           0 :                 return r;
    1279           0 :         if (r == 0)
    1280           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1281             : 
    1282           0 :         r = attach_device(m, seat, sysfs);
    1283           0 :         if (r < 0)
    1284           0 :                 return r;
    1285             : 
    1286           0 :         return sd_bus_reply_method_return(message, NULL);
    1287             : }
    1288             : 
    1289           0 : static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1290           0 :         Manager *m = userdata;
    1291             :         int interactive, r;
    1292             : 
    1293           0 :         assert(message);
    1294           0 :         assert(m);
    1295             : 
    1296           0 :         r = sd_bus_message_read(message, "b", &interactive);
    1297           0 :         if (r < 0)
    1298           0 :                 return r;
    1299             : 
    1300           0 :         r = bus_verify_polkit_async(
    1301             :                         message,
    1302             :                         CAP_SYS_ADMIN,
    1303             :                         "org.freedesktop.login1.flush-devices",
    1304             :                         interactive,
    1305             :                         UID_INVALID,
    1306             :                         &m->polkit_registry,
    1307             :                         error);
    1308           0 :         if (r < 0)
    1309           0 :                 return r;
    1310           0 :         if (r == 0)
    1311           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1312             : 
    1313           0 :         r = flush_devices(m);
    1314           0 :         if (r < 0)
    1315           0 :                 return r;
    1316             : 
    1317           0 :         return sd_bus_reply_method_return(message, NULL);
    1318             : }
    1319             : 
    1320           0 : static int have_multiple_sessions(
    1321             :                 Manager *m,
    1322             :                 uid_t uid) {
    1323             : 
    1324             :         Session *session;
    1325             :         Iterator i;
    1326             : 
    1327           0 :         assert(m);
    1328             : 
    1329             :         /* Check for other users' sessions. Greeter sessions do not
    1330             :          * count, and non-login sessions do not count either. */
    1331           0 :         HASHMAP_FOREACH(session, m->sessions, i)
    1332           0 :                 if (session->class == SESSION_USER &&
    1333           0 :                     session->user->uid != uid)
    1334           0 :                         return true;
    1335             : 
    1336           0 :         return false;
    1337             : }
    1338             : 
    1339           0 : static int bus_manager_log_shutdown(
    1340             :                 Manager *m,
    1341             :                 InhibitWhat w,
    1342             :                 const char *unit_name) {
    1343             : 
    1344             :         const char *p, *q;
    1345             : 
    1346           0 :         assert(m);
    1347           0 :         assert(unit_name);
    1348             : 
    1349           0 :         if (w != INHIBIT_SHUTDOWN)
    1350           0 :                 return 0;
    1351             : 
    1352           0 :         if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
    1353           0 :                 p = "MESSAGE=System is powering down.";
    1354           0 :                 q = "SHUTDOWN=power-off";
    1355           0 :         } else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
    1356           0 :                 p = "MESSAGE=System is halting.";
    1357           0 :                 q = "SHUTDOWN=halt";
    1358           0 :         } else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
    1359           0 :                 p = "MESSAGE=System is rebooting.";
    1360           0 :                 q = "SHUTDOWN=reboot";
    1361           0 :         } else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
    1362           0 :                 p = "MESSAGE=System is rebooting with kexec.";
    1363           0 :                 q = "SHUTDOWN=kexec";
    1364             :         } else {
    1365           0 :                 p = "MESSAGE=System is shutting down.";
    1366           0 :                 q = NULL;
    1367             :         }
    1368             : 
    1369           0 :         return log_struct(LOG_NOTICE,
    1370             :                           LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
    1371             :                           p,
    1372             :                           q,
    1373             :                           NULL);
    1374             : }
    1375             : 
    1376           0 : static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
    1377           0 :         Manager *m = userdata;
    1378             : 
    1379           0 :         assert(e);
    1380           0 :         assert(m);
    1381             : 
    1382           0 :         m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
    1383           0 :         return 0;
    1384             : }
    1385             : 
    1386           0 : int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
    1387             :         int r;
    1388             : 
    1389           0 :         assert(m);
    1390             : 
    1391           0 :         if (until <= now(CLOCK_MONOTONIC))
    1392           0 :                 return 0;
    1393             : 
    1394             :         /* We want to ignore the lid switch for a while after each
    1395             :          * suspend, and after boot-up. Hence let's install a timer for
    1396             :          * this. As long as the event source exists we ignore the lid
    1397             :          * switch. */
    1398             : 
    1399           0 :         if (m->lid_switch_ignore_event_source) {
    1400             :                 usec_t u;
    1401             : 
    1402           0 :                 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
    1403           0 :                 if (r < 0)
    1404           0 :                         return r;
    1405             : 
    1406           0 :                 if (until <= u)
    1407           0 :                         return 0;
    1408             : 
    1409           0 :                 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
    1410             :         } else
    1411           0 :                 r = sd_event_add_time(
    1412             :                                 m->event,
    1413             :                                 &m->lid_switch_ignore_event_source,
    1414             :                                 CLOCK_MONOTONIC,
    1415             :                                 until, 0,
    1416             :                                 lid_switch_ignore_handler, m);
    1417             : 
    1418           0 :         return r;
    1419             : }
    1420             : 
    1421           0 : static int execute_shutdown_or_sleep(
    1422             :                 Manager *m,
    1423             :                 InhibitWhat w,
    1424             :                 const char *unit_name,
    1425             :                 sd_bus_error *error) {
    1426             : 
    1427           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    1428             :         const char *p;
    1429             :         char *c;
    1430             :         int r;
    1431             : 
    1432           0 :         assert(m);
    1433           0 :         assert(w >= 0);
    1434           0 :         assert(w < _INHIBIT_WHAT_MAX);
    1435           0 :         assert(unit_name);
    1436             : 
    1437           0 :         bus_manager_log_shutdown(m, w, unit_name);
    1438             : 
    1439           0 :         r = sd_bus_call_method(
    1440             :                         m->bus,
    1441             :                         "org.freedesktop.systemd1",
    1442             :                         "/org/freedesktop/systemd1",
    1443             :                         "org.freedesktop.systemd1.Manager",
    1444             :                         "StartUnit",
    1445             :                         error,
    1446             :                         &reply,
    1447             :                         "ss", unit_name, "replace-irreversibly");
    1448           0 :         if (r < 0)
    1449           0 :                 return r;
    1450             : 
    1451           0 :         r = sd_bus_message_read(reply, "o", &p);
    1452           0 :         if (r < 0)
    1453           0 :                 return r;
    1454             : 
    1455           0 :         c = strdup(p);
    1456           0 :         if (!c)
    1457           0 :                 return -ENOMEM;
    1458             : 
    1459           0 :         m->action_unit = unit_name;
    1460           0 :         free(m->action_job);
    1461           0 :         m->action_job = c;
    1462           0 :         m->action_what = w;
    1463             : 
    1464             :         /* Make sure the lid switch is ignored for a while */
    1465           0 :         manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
    1466             : 
    1467           0 :         return 0;
    1468             : }
    1469             : 
    1470           0 : int manager_dispatch_delayed(Manager *manager, bool timeout) {
    1471             : 
    1472           0 :         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
    1473           0 :         Inhibitor *offending = NULL;
    1474             :         int r;
    1475             : 
    1476           0 :         assert(manager);
    1477             : 
    1478           0 :         if (manager->action_what == 0 || manager->action_job)
    1479           0 :                 return 0;
    1480             : 
    1481           0 :         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
    1482           0 :                 _cleanup_free_ char *comm = NULL, *u = NULL;
    1483             : 
    1484           0 :                 if (!timeout)
    1485           0 :                         return 0;
    1486             : 
    1487           0 :                 (void) get_process_comm(offending->pid, &comm);
    1488           0 :                 u = uid_to_name(offending->uid);
    1489             : 
    1490           0 :                 log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
    1491             :                            offending->uid, strna(u),
    1492             :                            offending->pid, strna(comm));
    1493             :         }
    1494             : 
    1495             :         /* Actually do the operation */
    1496           0 :         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
    1497           0 :         if (r < 0) {
    1498           0 :                 log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
    1499             : 
    1500           0 :                 manager->action_unit = NULL;
    1501           0 :                 manager->action_what = 0;
    1502           0 :                 return r;
    1503             :         }
    1504             : 
    1505           0 :         return 1;
    1506             : }
    1507             : 
    1508           0 : static int manager_inhibit_timeout_handler(
    1509             :                         sd_event_source *s,
    1510             :                         uint64_t usec,
    1511             :                         void *userdata) {
    1512             : 
    1513           0 :         Manager *manager = userdata;
    1514             :         int r;
    1515             : 
    1516           0 :         assert(manager);
    1517           0 :         assert(manager->inhibit_timeout_source == s);
    1518             : 
    1519           0 :         r = manager_dispatch_delayed(manager, true);
    1520           0 :         return (r < 0) ? r : 0;
    1521             : }
    1522             : 
    1523           0 : static int delay_shutdown_or_sleep(
    1524             :                 Manager *m,
    1525             :                 InhibitWhat w,
    1526             :                 const char *unit_name) {
    1527             : 
    1528             :         int r;
    1529             :         usec_t timeout_val;
    1530             : 
    1531           0 :         assert(m);
    1532           0 :         assert(w >= 0);
    1533           0 :         assert(w < _INHIBIT_WHAT_MAX);
    1534           0 :         assert(unit_name);
    1535             : 
    1536           0 :         timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
    1537             : 
    1538           0 :         if (m->inhibit_timeout_source) {
    1539           0 :                 r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
    1540           0 :                 if (r < 0)
    1541           0 :                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
    1542             : 
    1543           0 :                 r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
    1544           0 :                 if (r < 0)
    1545           0 :                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
    1546             :         } else {
    1547           0 :                 r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
    1548             :                                       timeout_val, 0, manager_inhibit_timeout_handler, m);
    1549           0 :                 if (r < 0)
    1550           0 :                         return r;
    1551             :         }
    1552             : 
    1553           0 :         m->action_unit = unit_name;
    1554           0 :         m->action_what = w;
    1555             : 
    1556           0 :         return 0;
    1557             : }
    1558             : 
    1559           0 : static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
    1560             : 
    1561             :         static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
    1562             :                 [INHIBIT_SHUTDOWN] = "PrepareForShutdown",
    1563             :                 [INHIBIT_SLEEP] = "PrepareForSleep"
    1564             :         };
    1565             : 
    1566           0 :         int active = _active;
    1567             : 
    1568           0 :         assert(m);
    1569           0 :         assert(w >= 0);
    1570           0 :         assert(w < _INHIBIT_WHAT_MAX);
    1571           0 :         assert(signal_name[w]);
    1572             : 
    1573           0 :         return sd_bus_emit_signal(m->bus,
    1574             :                                   "/org/freedesktop/login1",
    1575             :                                   "org.freedesktop.login1.Manager",
    1576             :                                   signal_name[w],
    1577             :                                   "b",
    1578             :                                   active);
    1579             : }
    1580             : 
    1581           0 : int bus_manager_shutdown_or_sleep_now_or_later(
    1582             :                 Manager *m,
    1583             :                 const char *unit_name,
    1584             :                 InhibitWhat w,
    1585             :                 sd_bus_error *error) {
    1586             : 
    1587             :         bool delayed;
    1588             :         int r;
    1589             : 
    1590           0 :         assert(m);
    1591           0 :         assert(unit_name);
    1592           0 :         assert(w >= 0);
    1593           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    1594           0 :         assert(!m->action_job);
    1595             : 
    1596             :         /* Tell everybody to prepare for shutdown/sleep */
    1597           0 :         send_prepare_for(m, w, true);
    1598             : 
    1599           0 :         delayed =
    1600           0 :                 m->inhibit_delay_max > 0 &&
    1601           0 :                 manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
    1602             : 
    1603           0 :         if (delayed)
    1604             :                 /* Shutdown is delayed, keep in mind what we
    1605             :                  * want to do, and start a timeout */
    1606           0 :                 r = delay_shutdown_or_sleep(m, w, unit_name);
    1607             :         else
    1608             :                 /* Shutdown is not delayed, execute it
    1609             :                  * immediately */
    1610           0 :                 r = execute_shutdown_or_sleep(m, w, unit_name, error);
    1611             : 
    1612           0 :         return r;
    1613             : }
    1614             : 
    1615           0 : static int verify_shutdown_creds(
    1616             :                 Manager *m,
    1617             :                 sd_bus_message *message,
    1618             :                 InhibitWhat w,
    1619             :                 bool interactive,
    1620             :                 const char *action,
    1621             :                 const char *action_multiple_sessions,
    1622             :                 const char *action_ignore_inhibit,
    1623             :                 sd_bus_error *error) {
    1624             : 
    1625           0 :         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
    1626             :         bool multiple_sessions, blocked;
    1627             :         uid_t uid;
    1628             :         int r;
    1629             : 
    1630           0 :         assert(m);
    1631           0 :         assert(message);
    1632           0 :         assert(w >= 0);
    1633           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    1634             : 
    1635           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
    1636           0 :         if (r < 0)
    1637           0 :                 return r;
    1638             : 
    1639           0 :         r = sd_bus_creds_get_euid(creds, &uid);
    1640           0 :         if (r < 0)
    1641           0 :                 return r;
    1642             : 
    1643           0 :         r = have_multiple_sessions(m, uid);
    1644           0 :         if (r < 0)
    1645           0 :                 return r;
    1646             : 
    1647           0 :         multiple_sessions = r > 0;
    1648           0 :         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
    1649             : 
    1650           0 :         if (multiple_sessions && action_multiple_sessions) {
    1651           0 :                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error);
    1652           0 :                 if (r < 0)
    1653           0 :                         return r;
    1654           0 :                 if (r == 0)
    1655           0 :                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1656             :         }
    1657             : 
    1658           0 :         if (blocked && action_ignore_inhibit) {
    1659           0 :                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error);
    1660           0 :                 if (r < 0)
    1661           0 :                         return r;
    1662           0 :                 if (r == 0)
    1663           0 :                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1664             :         }
    1665             : 
    1666           0 :         if (!multiple_sessions && !blocked && action) {
    1667           0 :                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error);
    1668           0 :                 if (r < 0)
    1669           0 :                         return r;
    1670           0 :                 if (r == 0)
    1671           0 :                         return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1672             :         }
    1673             : 
    1674           0 :         return 0;
    1675             : }
    1676             : 
    1677           0 : static int method_do_shutdown_or_sleep(
    1678             :                 Manager *m,
    1679             :                 sd_bus_message *message,
    1680             :                 const char *unit_name,
    1681             :                 InhibitWhat w,
    1682             :                 const char *action,
    1683             :                 const char *action_multiple_sessions,
    1684             :                 const char *action_ignore_inhibit,
    1685             :                 const char *sleep_verb,
    1686             :                 sd_bus_error *error) {
    1687             : 
    1688             :         int interactive, r;
    1689             : 
    1690           0 :         assert(m);
    1691           0 :         assert(message);
    1692           0 :         assert(unit_name);
    1693           0 :         assert(w >= 0);
    1694           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    1695             : 
    1696           0 :         r = sd_bus_message_read(message, "b", &interactive);
    1697           0 :         if (r < 0)
    1698           0 :                 return r;
    1699             : 
    1700             :         /* Don't allow multiple jobs being executed at the same time */
    1701           0 :         if (m->action_what)
    1702           0 :                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
    1703             : 
    1704           0 :         if (sleep_verb) {
    1705           0 :                 r = can_sleep(sleep_verb);
    1706           0 :                 if (r < 0)
    1707           0 :                         return r;
    1708             : 
    1709           0 :                 if (r == 0)
    1710           0 :                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
    1711             :         }
    1712             : 
    1713           0 :         r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
    1714             :                                   action_ignore_inhibit, error);
    1715           0 :         if (r != 0)
    1716           0 :                 return r;
    1717             : 
    1718           0 :         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
    1719           0 :         if (r < 0)
    1720           0 :                 return r;
    1721             : 
    1722           0 :         return sd_bus_reply_method_return(message, NULL);
    1723             : }
    1724             : 
    1725           0 : static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1726           0 :         Manager *m = userdata;
    1727             : 
    1728           0 :         return method_do_shutdown_or_sleep(
    1729             :                         m, message,
    1730             :                         SPECIAL_POWEROFF_TARGET,
    1731             :                         INHIBIT_SHUTDOWN,
    1732             :                         "org.freedesktop.login1.power-off",
    1733             :                         "org.freedesktop.login1.power-off-multiple-sessions",
    1734             :                         "org.freedesktop.login1.power-off-ignore-inhibit",
    1735             :                         NULL,
    1736             :                         error);
    1737             : }
    1738             : 
    1739           0 : static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1740           0 :         Manager *m = userdata;
    1741             : 
    1742           0 :         return method_do_shutdown_or_sleep(
    1743             :                         m, message,
    1744             :                         SPECIAL_REBOOT_TARGET,
    1745             :                         INHIBIT_SHUTDOWN,
    1746             :                         "org.freedesktop.login1.reboot",
    1747             :                         "org.freedesktop.login1.reboot-multiple-sessions",
    1748             :                         "org.freedesktop.login1.reboot-ignore-inhibit",
    1749             :                         NULL,
    1750             :                         error);
    1751             : }
    1752             : 
    1753           0 : static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1754           0 :         Manager *m = userdata;
    1755             : 
    1756           0 :         return method_do_shutdown_or_sleep(
    1757             :                         m, message,
    1758             :                         SPECIAL_SUSPEND_TARGET,
    1759             :                         INHIBIT_SLEEP,
    1760             :                         "org.freedesktop.login1.suspend",
    1761             :                         "org.freedesktop.login1.suspend-multiple-sessions",
    1762             :                         "org.freedesktop.login1.suspend-ignore-inhibit",
    1763             :                         "suspend",
    1764             :                         error);
    1765             : }
    1766             : 
    1767           0 : static int nologin_timeout_handler(
    1768             :                         sd_event_source *s,
    1769             :                         uint64_t usec,
    1770             :                         void *userdata) {
    1771             : 
    1772           0 :         Manager *m = userdata;
    1773             :         int r;
    1774             : 
    1775           0 :         log_info("Creating /run/nologin, blocking further logins...");
    1776             : 
    1777           0 :         r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
    1778           0 :         if (r < 0)
    1779           0 :                 log_error_errno(r, "Failed to create /run/nologin: %m");
    1780             :         else
    1781           0 :                 m->unlink_nologin = true;
    1782             : 
    1783           0 :         return 0;
    1784             : }
    1785             : 
    1786           0 : static int update_schedule_file(Manager *m) {
    1787             : 
    1788             :         int r;
    1789           0 :         _cleanup_fclose_ FILE *f = NULL;
    1790           0 :         _cleanup_free_ char *t = NULL, *temp_path = NULL;
    1791             : 
    1792           0 :         assert(m);
    1793             : 
    1794           0 :         r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
    1795           0 :         if (r < 0)
    1796           0 :                 return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
    1797             : 
    1798           0 :         t = cescape(m->wall_message);
    1799           0 :         if (!t)
    1800           0 :                 return log_oom();
    1801             : 
    1802           0 :         r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
    1803           0 :         if (r < 0)
    1804           0 :                 return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
    1805             : 
    1806           0 :         (void) fchmod(fileno(f), 0644);
    1807             : 
    1808           0 :         fprintf(f,
    1809             :                 "USEC="USEC_FMT"\n"
    1810             :                 "WARN_WALL=%i\n"
    1811             :                 "MODE=%s\n",
    1812             :                 m->scheduled_shutdown_timeout,
    1813             :                 m->enable_wall_messages,
    1814             :                 m->scheduled_shutdown_type);
    1815             : 
    1816           0 :         if (!isempty(m->wall_message))
    1817           0 :                 fprintf(f, "WALL_MESSAGE=%s\n", t);
    1818             : 
    1819           0 :         (void) fflush_and_check(f);
    1820             : 
    1821           0 :         if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
    1822           0 :                 log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
    1823           0 :                 r = -errno;
    1824             : 
    1825           0 :                 (void) unlink(temp_path);
    1826           0 :                 (void) unlink("/run/systemd/shutdown/scheduled");
    1827             :         }
    1828             : 
    1829           0 :         return r;
    1830             : }
    1831             : 
    1832           0 : static int manager_scheduled_shutdown_handler(
    1833             :                         sd_event_source *s,
    1834             :                         uint64_t usec,
    1835             :                         void *userdata) {
    1836             : 
    1837           0 :         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
    1838           0 :         Manager *m = userdata;
    1839             :         const char *target;
    1840             :         int r;
    1841             : 
    1842           0 :         assert(m);
    1843             : 
    1844           0 :         if (isempty(m->scheduled_shutdown_type))
    1845           0 :                 return 0;
    1846             : 
    1847           0 :         if (streq(m->scheduled_shutdown_type, "halt"))
    1848           0 :                 target = SPECIAL_HALT_TARGET;
    1849           0 :         else if (streq(m->scheduled_shutdown_type, "poweroff"))
    1850           0 :                 target = SPECIAL_POWEROFF_TARGET;
    1851             :         else
    1852           0 :                 target = SPECIAL_REBOOT_TARGET;
    1853             : 
    1854           0 :         r = execute_shutdown_or_sleep(m, 0, target, &error);
    1855           0 :         if (r < 0)
    1856           0 :                 return log_error_errno(r, "Unable to execute transition to %s: %m", target);
    1857             : 
    1858           0 :         return 0;
    1859             : }
    1860             : 
    1861           0 : static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1862           0 :         Manager *m = userdata;
    1863           0 :         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
    1864           0 :         const char *action_multiple_sessions = NULL;
    1865           0 :         const char *action_ignore_inhibit = NULL;
    1866           0 :         const char *action = NULL;
    1867             :         uint64_t elapse;
    1868             :         char *type;
    1869             :         int r;
    1870             : 
    1871           0 :         assert(m);
    1872           0 :         assert(message);
    1873             : 
    1874           0 :         r = sd_bus_message_read(message, "st", &type, &elapse);
    1875           0 :         if (r < 0)
    1876           0 :                 return r;
    1877             : 
    1878           0 :         if (streq(type, "reboot")) {
    1879           0 :                 action = "org.freedesktop.login1.reboot";
    1880           0 :                 action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
    1881           0 :                 action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
    1882           0 :         } else if (streq(type, "halt")) {
    1883           0 :                 action = "org.freedesktop.login1.halt";
    1884           0 :                 action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
    1885           0 :                 action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
    1886           0 :         } else if (streq(type, "poweroff")) {
    1887           0 :                 action = "org.freedesktop.login1.poweroff";
    1888           0 :                 action_multiple_sessions = "org.freedesktop.login1.poweroff-multiple-sessions";
    1889           0 :                 action_ignore_inhibit = "org.freedesktop.login1.poweroff-ignore-inhibit";
    1890             :         } else
    1891           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
    1892             : 
    1893           0 :         r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
    1894             :                                   action, action_multiple_sessions, action_ignore_inhibit, error);
    1895           0 :         if (r != 0)
    1896           0 :                 return r;
    1897             : 
    1898           0 :         if (m->scheduled_shutdown_timeout_source) {
    1899           0 :                 r = sd_event_source_set_time(m->scheduled_shutdown_timeout_source, elapse);
    1900           0 :                 if (r < 0)
    1901           0 :                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
    1902             : 
    1903           0 :                 r = sd_event_source_set_enabled(m->scheduled_shutdown_timeout_source, SD_EVENT_ONESHOT);
    1904           0 :                 if (r < 0)
    1905           0 :                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
    1906             :         } else {
    1907           0 :                 r = sd_event_add_time(m->event, &m->scheduled_shutdown_timeout_source,
    1908             :                                       CLOCK_REALTIME, elapse, 0, manager_scheduled_shutdown_handler, m);
    1909           0 :                 if (r < 0)
    1910           0 :                         return log_error_errno(r, "sd_event_add_time() failed: %m");
    1911             :         }
    1912             : 
    1913           0 :         r = free_and_strdup(&m->scheduled_shutdown_type, type);
    1914           0 :         if (r < 0) {
    1915           0 :                 m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
    1916           0 :                 return log_oom();
    1917             :         }
    1918             : 
    1919           0 :         if (m->nologin_timeout_source) {
    1920           0 :                 r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
    1921           0 :                 if (r < 0)
    1922           0 :                         return log_error_errno(r, "sd_event_source_set_time() failed: %m");
    1923             : 
    1924           0 :                 r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
    1925           0 :                 if (r < 0)
    1926           0 :                         return log_error_errno(r, "sd_event_source_set_enabled() failed: %m");
    1927             :         } else {
    1928           0 :                 r = sd_event_add_time(m->event, &m->nologin_timeout_source,
    1929           0 :                                       CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
    1930           0 :                 if (r < 0)
    1931           0 :                         return log_error_errno(r, "sd_event_add_time() failed: %m");
    1932             :         }
    1933             : 
    1934           0 :         m->scheduled_shutdown_timeout = elapse;
    1935             : 
    1936           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
    1937           0 :         if (r >= 0) {
    1938             :                 const char *tty;
    1939             : 
    1940           0 :                 (void) sd_bus_creds_get_uid(creds, &m->scheduled_shutdown_uid);
    1941           0 :                 (void) sd_bus_creds_get_tty(creds, &tty);
    1942             : 
    1943           0 :                 r = free_and_strdup(&m->scheduled_shutdown_tty, tty);
    1944           0 :                 if (r < 0) {
    1945           0 :                         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
    1946           0 :                         return log_oom();
    1947             :                 }
    1948             :         }
    1949             : 
    1950           0 :         r = manager_setup_wall_message_timer(m);
    1951           0 :         if (r < 0)
    1952           0 :                 return r;
    1953             : 
    1954           0 :         if (!isempty(type)) {
    1955           0 :                 r = update_schedule_file(m);
    1956           0 :                 if (r < 0)
    1957           0 :                         return r;
    1958             :         } else
    1959           0 :                 (void) unlink("/run/systemd/shutdown/scheduled");
    1960             : 
    1961           0 :         return sd_bus_reply_method_return(message, NULL);
    1962             : }
    1963             : 
    1964           0 : static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1965           0 :         Manager *m = userdata;
    1966             :         bool cancelled;
    1967             : 
    1968           0 :         assert(m);
    1969           0 :         assert(message);
    1970             : 
    1971           0 :         cancelled = m->scheduled_shutdown_type != NULL;
    1972             : 
    1973           0 :         m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
    1974           0 :         m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
    1975           0 :         m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
    1976           0 :         free(m->scheduled_shutdown_type);
    1977           0 :         m->scheduled_shutdown_type = NULL;
    1978           0 :         m->scheduled_shutdown_timeout = 0;
    1979             : 
    1980           0 :         if (m->unlink_nologin) {
    1981           0 :                 (void) unlink("/run/nologin");
    1982           0 :                 m->unlink_nologin = false;
    1983             :         }
    1984             : 
    1985           0 :         if (cancelled) {
    1986           0 :                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
    1987           0 :                 const char *tty = NULL;
    1988           0 :                 uid_t uid = 0;
    1989             :                 int r;
    1990             : 
    1991           0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
    1992           0 :                 if (r >= 0) {
    1993           0 :                         (void) sd_bus_creds_get_uid(creds, &uid);
    1994           0 :                         (void) sd_bus_creds_get_tty(creds, &tty);
    1995             :                 }
    1996             : 
    1997           0 :                 utmp_wall("The system shutdown has been cancelled",
    1998           0 :                           lookup_uid(uid), tty, logind_wall_tty_filter, m);
    1999             :         }
    2000             : 
    2001           0 :         return sd_bus_reply_method_return(message, "b", cancelled);
    2002             : }
    2003             : 
    2004           0 : static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2005           0 :         Manager *m = userdata;
    2006             : 
    2007           0 :         return method_do_shutdown_or_sleep(
    2008             :                         m, message,
    2009             :                         SPECIAL_HIBERNATE_TARGET,
    2010             :                         INHIBIT_SLEEP,
    2011             :                         "org.freedesktop.login1.hibernate",
    2012             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2013             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2014             :                         "hibernate",
    2015             :                         error);
    2016             : }
    2017             : 
    2018           0 : static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2019           0 :         Manager *m = userdata;
    2020             : 
    2021           0 :         return method_do_shutdown_or_sleep(
    2022             :                         m, message,
    2023             :                         SPECIAL_HYBRID_SLEEP_TARGET,
    2024             :                         INHIBIT_SLEEP,
    2025             :                         "org.freedesktop.login1.hibernate",
    2026             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2027             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2028             :                         "hybrid-sleep",
    2029             :                         error);
    2030             : }
    2031             : 
    2032           0 : static int method_can_shutdown_or_sleep(
    2033             :                 Manager *m,
    2034             :                 sd_bus_message *message,
    2035             :                 InhibitWhat w,
    2036             :                 const char *action,
    2037             :                 const char *action_multiple_sessions,
    2038             :                 const char *action_ignore_inhibit,
    2039             :                 const char *sleep_verb,
    2040             :                 sd_bus_error *error) {
    2041             : 
    2042           0 :         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
    2043             :         bool multiple_sessions, challenge, blocked;
    2044           0 :         const char *result = NULL;
    2045             :         uid_t uid;
    2046             :         int r;
    2047             : 
    2048           0 :         assert(m);
    2049           0 :         assert(message);
    2050           0 :         assert(w >= 0);
    2051           0 :         assert(w <= _INHIBIT_WHAT_MAX);
    2052           0 :         assert(action);
    2053           0 :         assert(action_multiple_sessions);
    2054           0 :         assert(action_ignore_inhibit);
    2055             : 
    2056           0 :         if (sleep_verb) {
    2057           0 :                 r = can_sleep(sleep_verb);
    2058           0 :                 if (r < 0)
    2059           0 :                         return r;
    2060           0 :                 if (r == 0)
    2061           0 :                         return sd_bus_reply_method_return(message, "s", "na");
    2062             :         }
    2063             : 
    2064           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
    2065           0 :         if (r < 0)
    2066           0 :                 return r;
    2067             : 
    2068           0 :         r = sd_bus_creds_get_euid(creds, &uid);
    2069           0 :         if (r < 0)
    2070           0 :                 return r;
    2071             : 
    2072           0 :         r = have_multiple_sessions(m, uid);
    2073           0 :         if (r < 0)
    2074           0 :                 return r;
    2075             : 
    2076           0 :         multiple_sessions = r > 0;
    2077           0 :         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
    2078             : 
    2079           0 :         if (multiple_sessions) {
    2080           0 :                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error);
    2081           0 :                 if (r < 0)
    2082           0 :                         return r;
    2083             : 
    2084           0 :                 if (r > 0)
    2085           0 :                         result = "yes";
    2086           0 :                 else if (challenge)
    2087           0 :                         result = "challenge";
    2088             :                 else
    2089           0 :                         result = "no";
    2090             :         }
    2091             : 
    2092           0 :         if (blocked) {
    2093           0 :                 r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error);
    2094           0 :                 if (r < 0)
    2095           0 :                         return r;
    2096             : 
    2097           0 :                 if (r > 0 && !result)
    2098           0 :                         result = "yes";
    2099           0 :                 else if (challenge && (!result || streq(result, "yes")))
    2100           0 :                         result = "challenge";
    2101             :                 else
    2102           0 :                         result = "no";
    2103             :         }
    2104             : 
    2105           0 :         if (!multiple_sessions && !blocked) {
    2106             :                 /* If neither inhibit nor multiple sessions
    2107             :                  * apply then just check the normal policy */
    2108             : 
    2109           0 :                 r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error);
    2110           0 :                 if (r < 0)
    2111           0 :                         return r;
    2112             : 
    2113           0 :                 if (r > 0)
    2114           0 :                         result = "yes";
    2115           0 :                 else if (challenge)
    2116           0 :                         result = "challenge";
    2117             :                 else
    2118           0 :                         result = "no";
    2119             :         }
    2120             : 
    2121           0 :         return sd_bus_reply_method_return(message, "s", result);
    2122             : }
    2123             : 
    2124           0 : static int method_can_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2125           0 :         Manager *m = userdata;
    2126             : 
    2127           0 :         return method_can_shutdown_or_sleep(
    2128             :                         m, message,
    2129             :                         INHIBIT_SHUTDOWN,
    2130             :                         "org.freedesktop.login1.power-off",
    2131             :                         "org.freedesktop.login1.power-off-multiple-sessions",
    2132             :                         "org.freedesktop.login1.power-off-ignore-inhibit",
    2133             :                         NULL,
    2134             :                         error);
    2135             : }
    2136             : 
    2137           0 : static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2138           0 :         Manager *m = userdata;
    2139             : 
    2140           0 :         return method_can_shutdown_or_sleep(
    2141             :                         m, message,
    2142             :                         INHIBIT_SHUTDOWN,
    2143             :                         "org.freedesktop.login1.reboot",
    2144             :                         "org.freedesktop.login1.reboot-multiple-sessions",
    2145             :                         "org.freedesktop.login1.reboot-ignore-inhibit",
    2146             :                         NULL,
    2147             :                         error);
    2148             : }
    2149             : 
    2150           0 : static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2151           0 :         Manager *m = userdata;
    2152             : 
    2153           0 :         return method_can_shutdown_or_sleep(
    2154             :                         m, message,
    2155             :                         INHIBIT_SLEEP,
    2156             :                         "org.freedesktop.login1.suspend",
    2157             :                         "org.freedesktop.login1.suspend-multiple-sessions",
    2158             :                         "org.freedesktop.login1.suspend-ignore-inhibit",
    2159             :                         "suspend",
    2160             :                         error);
    2161             : }
    2162             : 
    2163           0 : static int method_can_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2164           0 :         Manager *m = userdata;
    2165             : 
    2166           0 :         return method_can_shutdown_or_sleep(
    2167             :                         m, message,
    2168             :                         INHIBIT_SLEEP,
    2169             :                         "org.freedesktop.login1.hibernate",
    2170             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2171             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2172             :                         "hibernate",
    2173             :                         error);
    2174             : }
    2175             : 
    2176           0 : static int method_can_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2177           0 :         Manager *m = userdata;
    2178             : 
    2179           0 :         return method_can_shutdown_or_sleep(
    2180             :                         m, message,
    2181             :                         INHIBIT_SLEEP,
    2182             :                         "org.freedesktop.login1.hibernate",
    2183             :                         "org.freedesktop.login1.hibernate-multiple-sessions",
    2184             :                         "org.freedesktop.login1.hibernate-ignore-inhibit",
    2185             :                         "hybrid-sleep",
    2186             :                         error);
    2187             : }
    2188             : 
    2189           0 : static int property_get_reboot_to_firmware_setup(
    2190             :                 sd_bus *bus,
    2191             :                 const char *path,
    2192             :                 const char *interface,
    2193             :                 const char *property,
    2194             :                 sd_bus_message *reply,
    2195             :                 void *userdata,
    2196             :                 sd_bus_error *error) {
    2197             :         int r;
    2198             : 
    2199           0 :         assert(bus);
    2200           0 :         assert(reply);
    2201           0 :         assert(userdata);
    2202             : 
    2203           0 :         r = efi_get_reboot_to_firmware();
    2204           0 :         if (r < 0 && r != -EOPNOTSUPP)
    2205           0 :                 return r;
    2206             : 
    2207           0 :         return sd_bus_message_append(reply, "b", r > 0);
    2208             : }
    2209             : 
    2210           0 : static int method_set_reboot_to_firmware_setup(
    2211             :                 sd_bus_message *message,
    2212             :                 void *userdata,
    2213             :                 sd_bus_error *error) {
    2214             : 
    2215             :         int b, r;
    2216           0 :         Manager *m = userdata;
    2217             : 
    2218           0 :         assert(message);
    2219           0 :         assert(m);
    2220             : 
    2221           0 :         r = sd_bus_message_read(message, "b", &b);
    2222           0 :         if (r < 0)
    2223           0 :                 return r;
    2224             : 
    2225           0 :         r = bus_verify_polkit_async(message,
    2226             :                                     CAP_SYS_ADMIN,
    2227             :                                     "org.freedesktop.login1.set-reboot-to-firmware-setup",
    2228             :                                     false,
    2229             :                                     UID_INVALID,
    2230             :                                     &m->polkit_registry,
    2231             :                                     error);
    2232           0 :         if (r < 0)
    2233           0 :                 return r;
    2234           0 :         if (r == 0)
    2235           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2236             : 
    2237           0 :         r = efi_set_reboot_to_firmware(b);
    2238           0 :         if (r < 0)
    2239           0 :                 return r;
    2240             : 
    2241           0 :         return sd_bus_reply_method_return(message, NULL);
    2242             : }
    2243             : 
    2244           0 : static int method_can_reboot_to_firmware_setup(
    2245             :                 sd_bus_message *message,
    2246             :                 void *userdata,
    2247             :                 sd_bus_error *error) {
    2248             : 
    2249             :         int r;
    2250             :         bool challenge;
    2251             :         const char *result;
    2252           0 :         Manager *m = userdata;
    2253             : 
    2254           0 :         assert(message);
    2255           0 :         assert(m);
    2256             : 
    2257           0 :         r = efi_reboot_to_firmware_supported();
    2258           0 :         if (r == -EOPNOTSUPP)
    2259           0 :                 return sd_bus_reply_method_return(message, "s", "na");
    2260           0 :         else if (r < 0)
    2261           0 :                 return r;
    2262             : 
    2263           0 :         r = bus_test_polkit(message,
    2264             :                             CAP_SYS_ADMIN,
    2265             :                             "org.freedesktop.login1.set-reboot-to-firmware-setup",
    2266             :                             UID_INVALID,
    2267             :                             &challenge,
    2268             :                             error);
    2269           0 :         if (r < 0)
    2270           0 :                 return r;
    2271             : 
    2272           0 :         if (r > 0)
    2273           0 :                 result = "yes";
    2274           0 :         else if (challenge)
    2275           0 :                 result = "challenge";
    2276             :         else
    2277           0 :                 result = "no";
    2278             : 
    2279           0 :         return sd_bus_reply_method_return(message, "s", result);
    2280             : }
    2281             : 
    2282           0 : static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2283           0 :         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
    2284             :         const char *who, *why, *what, *mode;
    2285           0 :         _cleanup_free_ char *id = NULL;
    2286           0 :         _cleanup_close_ int fifo_fd = -1;
    2287           0 :         Manager *m = userdata;
    2288           0 :         Inhibitor *i = NULL;
    2289             :         InhibitMode mm;
    2290             :         InhibitWhat w;
    2291             :         pid_t pid;
    2292             :         uid_t uid;
    2293             :         int r;
    2294             : 
    2295           0 :         assert(message);
    2296           0 :         assert(m);
    2297             : 
    2298           0 :         r = sd_bus_message_read(message, "ssss", &what, &who, &why, &mode);
    2299           0 :         if (r < 0)
    2300           0 :                 return r;
    2301             : 
    2302           0 :         w = inhibit_what_from_string(what);
    2303           0 :         if (w <= 0)
    2304           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid what specification %s", what);
    2305             : 
    2306           0 :         mm = inhibit_mode_from_string(mode);
    2307           0 :         if (mm < 0)
    2308           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid mode specification %s", mode);
    2309             : 
    2310             :         /* Delay is only supported for shutdown/sleep */
    2311           0 :         if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP)))
    2312           0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
    2313             : 
    2314             :         /* Don't allow taking delay locks while we are already
    2315             :          * executing the operation. We shouldn't create the impression
    2316             :          * that the lock was successful if the machine is about to go
    2317             :          * down/suspend any moment. */
    2318           0 :         if (m->action_what & w)
    2319           0 :                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
    2320             : 
    2321           0 :         r = bus_verify_polkit_async(
    2322             :                         message,
    2323             :                         CAP_SYS_BOOT,
    2324           0 :                         w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
    2325           0 :                         w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
    2326           0 :                         w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
    2327           0 :                         w == INHIBIT_HANDLE_POWER_KEY     ? "org.freedesktop.login1.inhibit-handle-power-key" :
    2328           0 :                         w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
    2329           0 :                         w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
    2330             :                                                             "org.freedesktop.login1.inhibit-handle-lid-switch",
    2331             :                         false,
    2332             :                         UID_INVALID,
    2333             :                         &m->polkit_registry,
    2334             :                         error);
    2335           0 :         if (r < 0)
    2336           0 :                 return r;
    2337           0 :         if (r == 0)
    2338           0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2339             : 
    2340           0 :         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
    2341           0 :         if (r < 0)
    2342           0 :                 return r;
    2343             : 
    2344           0 :         r = sd_bus_creds_get_euid(creds, &uid);
    2345           0 :         if (r < 0)
    2346           0 :                 return r;
    2347             : 
    2348           0 :         r = sd_bus_creds_get_pid(creds, &pid);
    2349           0 :         if (r < 0)
    2350           0 :                 return r;
    2351             : 
    2352             :         do {
    2353           0 :                 free(id);
    2354           0 :                 id = NULL;
    2355             : 
    2356           0 :                 if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0)
    2357           0 :                         return -ENOMEM;
    2358             : 
    2359           0 :         } while (hashmap_get(m->inhibitors, id));
    2360             : 
    2361           0 :         r = manager_add_inhibitor(m, id, &i);
    2362           0 :         if (r < 0)
    2363           0 :                 return r;
    2364             : 
    2365           0 :         i->what = w;
    2366           0 :         i->mode = mm;
    2367           0 :         i->pid = pid;
    2368           0 :         i->uid = uid;
    2369           0 :         i->why = strdup(why);
    2370           0 :         i->who = strdup(who);
    2371             : 
    2372           0 :         if (!i->why || !i->who) {
    2373           0 :                 r = -ENOMEM;
    2374           0 :                 goto fail;
    2375             :         }
    2376             : 
    2377           0 :         fifo_fd = inhibitor_create_fifo(i);
    2378           0 :         if (fifo_fd < 0) {
    2379           0 :                 r = fifo_fd;
    2380           0 :                 goto fail;
    2381             :         }
    2382             : 
    2383           0 :         inhibitor_start(i);
    2384             : 
    2385           0 :         return sd_bus_reply_method_return(message, "h", fifo_fd);
    2386             : 
    2387             : fail:
    2388           0 :         if (i)
    2389           0 :                 inhibitor_free(i);
    2390             : 
    2391           0 :         return r;
    2392             : }
    2393             : 
    2394             : const sd_bus_vtable manager_vtable[] = {
    2395             :         SD_BUS_VTABLE_START(0),
    2396             : 
    2397             :         SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
    2398             :         SD_BUS_WRITABLE_PROPERTY("WallMessage", "s", NULL, NULL, offsetof(Manager, wall_message), 0),
    2399             : 
    2400             :         SD_BUS_PROPERTY("NAutoVTs", "u", NULL, offsetof(Manager, n_autovts), SD_BUS_VTABLE_PROPERTY_CONST),
    2401             :         SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
    2402             :         SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
    2403             :         SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
    2404             :         SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2405             :         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    2406             :         SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    2407             :         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    2408             :         SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    2409             :         SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    2410             :         SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
    2411             :         SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
    2412             :         SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
    2413             :         SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
    2414             :         SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
    2415             :         SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
    2416             :         SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    2417             :         SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
    2418             :         SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    2419             :         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
    2420             :         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
    2421             :         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
    2422             :         SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
    2423             : 
    2424             :         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
    2425             :         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
    2426             :         SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
    2427             :         SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
    2428             :         SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
    2429             :         SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
    2430             :         SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
    2431             :         SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
    2432             :         SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
    2433             :         SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
    2434             :         SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
    2435             :         SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
    2436             :         SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
    2437             :         SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
    2438             :         SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
    2439             :         SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
    2440             :         SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
    2441             :         SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
    2442             :         SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
    2443             :         SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
    2444             :         SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
    2445             :         SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
    2446             :         SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
    2447             :         SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
    2448             :         SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
    2449             :         SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
    2450             :         SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
    2451             :         SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
    2452             :         SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
    2453             :         SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
    2454             :         SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
    2455             :         SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
    2456             :         SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
    2457             :         SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
    2458             :         SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
    2459             :         SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
    2460             :         SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
    2461             :         SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
    2462             :         SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
    2463             :         SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
    2464             : 
    2465             :         SD_BUS_SIGNAL("SessionNew", "so", 0),
    2466             :         SD_BUS_SIGNAL("SessionRemoved", "so", 0),
    2467             :         SD_BUS_SIGNAL("UserNew", "uo", 0),
    2468             :         SD_BUS_SIGNAL("UserRemoved", "uo", 0),
    2469             :         SD_BUS_SIGNAL("SeatNew", "so", 0),
    2470             :         SD_BUS_SIGNAL("SeatRemoved", "so", 0),
    2471             :         SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
    2472             :         SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
    2473             : 
    2474             :         SD_BUS_VTABLE_END
    2475             : };
    2476             : 
    2477           0 : static int session_jobs_reply(Session *s, const char *unit, const char *result) {
    2478           0 :         int r = 0;
    2479             : 
    2480           0 :         assert(s);
    2481           0 :         assert(unit);
    2482             : 
    2483           0 :         if (!s->started)
    2484           0 :                 return r;
    2485             : 
    2486           0 :         if (streq(result, "done"))
    2487           0 :                 r = session_send_create_reply(s, NULL);
    2488             :         else {
    2489           0 :                 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
    2490             : 
    2491           0 :                 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
    2492           0 :                 r = session_send_create_reply(s, &e);
    2493             :         }
    2494             : 
    2495           0 :         return r;
    2496             : }
    2497             : 
    2498           0 : int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2499             :         const char *path, *result, *unit;
    2500           0 :         Manager *m = userdata;
    2501             :         Session *session;
    2502             :         uint32_t id;
    2503             :         User *user;
    2504             :         int r;
    2505             : 
    2506           0 :         assert(message);
    2507           0 :         assert(m);
    2508             : 
    2509           0 :         r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
    2510           0 :         if (r < 0) {
    2511           0 :                 bus_log_parse_error(r);
    2512           0 :                 return r;
    2513             :         }
    2514             : 
    2515           0 :         if (m->action_job && streq(m->action_job, path)) {
    2516           0 :                 log_info("Operation finished.");
    2517             : 
    2518             :                 /* Tell people that they now may take a lock again */
    2519           0 :                 send_prepare_for(m, m->action_what, false);
    2520             : 
    2521           0 :                 free(m->action_job);
    2522           0 :                 m->action_job = NULL;
    2523           0 :                 m->action_unit = NULL;
    2524           0 :                 m->action_what = 0;
    2525           0 :                 return 0;
    2526             :         }
    2527             : 
    2528           0 :         session = hashmap_get(m->session_units, unit);
    2529           0 :         if (session) {
    2530             : 
    2531           0 :                 if (streq_ptr(path, session->scope_job)) {
    2532           0 :                         free(session->scope_job);
    2533           0 :                         session->scope_job = NULL;
    2534             :                 }
    2535             : 
    2536           0 :                 session_jobs_reply(session, unit, result);
    2537             : 
    2538           0 :                 session_save(session);
    2539           0 :                 user_save(session->user);
    2540           0 :                 session_add_to_gc_queue(session);
    2541             :         }
    2542             : 
    2543           0 :         user = hashmap_get(m->user_units, unit);
    2544           0 :         if (user) {
    2545             : 
    2546           0 :                 if (streq_ptr(path, user->service_job)) {
    2547           0 :                         free(user->service_job);
    2548           0 :                         user->service_job = NULL;
    2549             :                 }
    2550             : 
    2551           0 :                 if (streq_ptr(path, user->slice_job)) {
    2552           0 :                         free(user->slice_job);
    2553           0 :                         user->slice_job = NULL;
    2554             :                 }
    2555             : 
    2556           0 :                 LIST_FOREACH(sessions_by_user, session, user->sessions) {
    2557           0 :                         session_jobs_reply(session, unit, result);
    2558             :                 }
    2559             : 
    2560           0 :                 user_save(user);
    2561           0 :                 user_add_to_gc_queue(user);
    2562             :         }
    2563             : 
    2564           0 :         return 0;
    2565             : }
    2566             : 
    2567           0 : int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2568             :         const char *path, *unit;
    2569           0 :         Manager *m = userdata;
    2570             :         Session *session;
    2571             :         User *user;
    2572             :         int r;
    2573             : 
    2574           0 :         assert(message);
    2575           0 :         assert(m);
    2576             : 
    2577           0 :         r = sd_bus_message_read(message, "so", &unit, &path);
    2578           0 :         if (r < 0) {
    2579           0 :                 bus_log_parse_error(r);
    2580           0 :                 return r;
    2581             :         }
    2582             : 
    2583           0 :         session = hashmap_get(m->session_units, unit);
    2584           0 :         if (session)
    2585           0 :                 session_add_to_gc_queue(session);
    2586             : 
    2587           0 :         user = hashmap_get(m->user_units, unit);
    2588           0 :         if (user)
    2589           0 :                 user_add_to_gc_queue(user);
    2590             : 
    2591           0 :         return 0;
    2592             : }
    2593             : 
    2594           0 : int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2595           0 :         _cleanup_free_ char *unit = NULL;
    2596           0 :         Manager *m = userdata;
    2597             :         const char *path;
    2598             :         Session *session;
    2599             :         User *user;
    2600             :         int r;
    2601             : 
    2602           0 :         assert(message);
    2603           0 :         assert(m);
    2604             : 
    2605           0 :         path = sd_bus_message_get_path(message);
    2606           0 :         if (!path)
    2607           0 :                 return 0;
    2608             : 
    2609           0 :         r = unit_name_from_dbus_path(path, &unit);
    2610           0 :         if (r == -EINVAL) /* not a unit */
    2611           0 :                 return 0;
    2612           0 :         if (r < 0)
    2613           0 :                 return r;
    2614             : 
    2615           0 :         session = hashmap_get(m->session_units, unit);
    2616           0 :         if (session)
    2617           0 :                 session_add_to_gc_queue(session);
    2618             : 
    2619           0 :         user = hashmap_get(m->user_units, unit);
    2620           0 :         if (user)
    2621           0 :                 user_add_to_gc_queue(user);
    2622             : 
    2623           0 :         return 0;
    2624             : }
    2625             : 
    2626           0 : int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2627           0 :         Manager *m = userdata;
    2628             :         Session *session;
    2629             :         Iterator i;
    2630             :         int b, r;
    2631             : 
    2632           0 :         assert(message);
    2633           0 :         assert(m);
    2634             : 
    2635           0 :         r = sd_bus_message_read(message, "b", &b);
    2636           0 :         if (r < 0) {
    2637           0 :                 bus_log_parse_error(r);
    2638           0 :                 return r;
    2639             :         }
    2640             : 
    2641           0 :         if (b)
    2642           0 :                 return 0;
    2643             : 
    2644             :         /* systemd finished reloading, let's recheck all our sessions */
    2645           0 :         log_debug("System manager has been reloaded, rechecking sessions...");
    2646             : 
    2647           0 :         HASHMAP_FOREACH(session, m->sessions, i)
    2648           0 :                 session_add_to_gc_queue(session);
    2649             : 
    2650           0 :         return 0;
    2651             : }
    2652             : 
    2653           0 : int match_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2654             :         const char *name, *old, *new;
    2655           0 :         Manager *m = userdata;
    2656             :         Session *session;
    2657             :         Iterator i;
    2658             :         int r;
    2659             :         char *key;
    2660             : 
    2661           0 :         assert(message);
    2662           0 :         assert(m);
    2663             : 
    2664           0 :         r = sd_bus_message_read(message, "sss", &name, &old, &new);
    2665           0 :         if (r < 0) {
    2666           0 :                 bus_log_parse_error(r);
    2667           0 :                 return r;
    2668             :         }
    2669             : 
    2670           0 :         if (isempty(old) || !isempty(new))
    2671           0 :                 return 0;
    2672             : 
    2673           0 :         key = set_remove(m->busnames, (char*) old);
    2674           0 :         if (!key)
    2675           0 :                 return 0;
    2676             : 
    2677             :         /* Drop all controllers owned by this name */
    2678             : 
    2679           0 :         free(key);
    2680             : 
    2681           0 :         HASHMAP_FOREACH(session, m->sessions, i)
    2682           0 :                 if (session_is_controller(session, old))
    2683           0 :                         session_drop_controller(session);
    2684             : 
    2685           0 :         return 0;
    2686             : }
    2687             : 
    2688           0 : int manager_send_changed(Manager *manager, const char *property, ...) {
    2689             :         char **l;
    2690             : 
    2691           0 :         assert(manager);
    2692             : 
    2693           0 :         l = strv_from_stdarg_alloca(property);
    2694             : 
    2695           0 :         return sd_bus_emit_properties_changed_strv(
    2696             :                         manager->bus,
    2697             :                         "/org/freedesktop/login1",
    2698             :                         "org.freedesktop.login1.Manager",
    2699             :                         l);
    2700             : }
    2701             : 
    2702           0 : int manager_start_scope(
    2703             :                 Manager *manager,
    2704             :                 const char *scope,
    2705             :                 pid_t pid,
    2706             :                 const char *slice,
    2707             :                 const char *description,
    2708             :                 const char *after, const char *after2,
    2709             :                 sd_bus_error *error,
    2710             :                 char **job) {
    2711             : 
    2712           0 :         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
    2713             :         int r;
    2714             : 
    2715           0 :         assert(manager);
    2716           0 :         assert(scope);
    2717           0 :         assert(pid > 1);
    2718             : 
    2719           0 :         r = sd_bus_message_new_method_call(
    2720             :                         manager->bus,
    2721             :                         &m,
    2722             :                         "org.freedesktop.systemd1",
    2723             :                         "/org/freedesktop/systemd1",
    2724             :                         "org.freedesktop.systemd1.Manager",
    2725             :                         "StartTransientUnit");
    2726           0 :         if (r < 0)
    2727           0 :                 return r;
    2728             : 
    2729           0 :         r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
    2730           0 :         if (r < 0)
    2731           0 :                 return r;
    2732             : 
    2733           0 :         r = sd_bus_message_open_container(m, 'a', "(sv)");
    2734           0 :         if (r < 0)
    2735           0 :                 return r;
    2736             : 
    2737           0 :         if (!isempty(slice)) {
    2738           0 :                 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
    2739           0 :                 if (r < 0)
    2740           0 :                         return r;
    2741             :         }
    2742             : 
    2743           0 :         if (!isempty(description)) {
    2744           0 :                 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
    2745           0 :                 if (r < 0)
    2746           0 :                         return r;
    2747             :         }
    2748             : 
    2749           0 :         if (!isempty(after)) {
    2750           0 :                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
    2751           0 :                 if (r < 0)
    2752           0 :                         return r;
    2753             :         }
    2754             : 
    2755           0 :         if (!isempty(after2)) {
    2756           0 :                 r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
    2757           0 :                 if (r < 0)
    2758           0 :                         return r;
    2759             :         }
    2760             : 
    2761             :         /* cgroup empty notification is not available in containers
    2762             :          * currently. To make this less problematic, let's shorten the
    2763             :          * stop timeout for sessions, so that we don't wait
    2764             :          * forever. */
    2765             : 
    2766             :         /* Make sure that the session shells are terminated with
    2767             :          * SIGHUP since bash and friends tend to ignore SIGTERM */
    2768           0 :         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
    2769           0 :         if (r < 0)
    2770           0 :                 return r;
    2771             : 
    2772           0 :         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
    2773           0 :         if (r < 0)
    2774           0 :                 return r;
    2775             : 
    2776           0 :         r = sd_bus_message_close_container(m);
    2777           0 :         if (r < 0)
    2778           0 :                 return r;
    2779             : 
    2780           0 :         r = sd_bus_message_append(m, "a(sa(sv))", 0);
    2781           0 :         if (r < 0)
    2782           0 :                 return r;
    2783             : 
    2784           0 :         r = sd_bus_call(manager->bus, m, 0, error, &reply);
    2785           0 :         if (r < 0)
    2786           0 :                 return r;
    2787             : 
    2788           0 :         if (job) {
    2789             :                 const char *j;
    2790             :                 char *copy;
    2791             : 
    2792           0 :                 r = sd_bus_message_read(reply, "o", &j);
    2793           0 :                 if (r < 0)
    2794           0 :                         return r;
    2795             : 
    2796           0 :                 copy = strdup(j);
    2797           0 :                 if (!copy)
    2798           0 :                         return -ENOMEM;
    2799             : 
    2800           0 :                 *job = copy;
    2801             :         }
    2802             : 
    2803           0 :         return 1;
    2804             : }
    2805             : 
    2806           0 : int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
    2807           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    2808             :         int r;
    2809             : 
    2810           0 :         assert(manager);
    2811           0 :         assert(unit);
    2812             : 
    2813           0 :         r = sd_bus_call_method(
    2814             :                         manager->bus,
    2815             :                         "org.freedesktop.systemd1",
    2816             :                         "/org/freedesktop/systemd1",
    2817             :                         "org.freedesktop.systemd1.Manager",
    2818             :                         "StartUnit",
    2819             :                         error,
    2820             :                         &reply,
    2821             :                         "ss", unit, "fail");
    2822           0 :         if (r < 0)
    2823           0 :                 return r;
    2824             : 
    2825           0 :         if (job) {
    2826             :                 const char *j;
    2827             :                 char *copy;
    2828             : 
    2829           0 :                 r = sd_bus_message_read(reply, "o", &j);
    2830           0 :                 if (r < 0)
    2831           0 :                         return r;
    2832             : 
    2833           0 :                 copy = strdup(j);
    2834           0 :                 if (!copy)
    2835           0 :                         return -ENOMEM;
    2836             : 
    2837           0 :                 *job = copy;
    2838             :         }
    2839             : 
    2840           0 :         return 1;
    2841             : }
    2842             : 
    2843           0 : int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
    2844           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    2845             :         int r;
    2846             : 
    2847           0 :         assert(manager);
    2848           0 :         assert(unit);
    2849             : 
    2850           0 :         r = sd_bus_call_method(
    2851             :                         manager->bus,
    2852             :                         "org.freedesktop.systemd1",
    2853             :                         "/org/freedesktop/systemd1",
    2854             :                         "org.freedesktop.systemd1.Manager",
    2855             :                         "StopUnit",
    2856             :                         error,
    2857             :                         &reply,
    2858             :                         "ss", unit, "fail");
    2859           0 :         if (r < 0) {
    2860           0 :                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
    2861           0 :                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
    2862             : 
    2863           0 :                         if (job)
    2864           0 :                                 *job = NULL;
    2865             : 
    2866           0 :                         sd_bus_error_free(error);
    2867           0 :                         return 0;
    2868             :                 }
    2869             : 
    2870           0 :                 return r;
    2871             :         }
    2872             : 
    2873           0 :         if (job) {
    2874             :                 const char *j;
    2875             :                 char *copy;
    2876             : 
    2877           0 :                 r = sd_bus_message_read(reply, "o", &j);
    2878           0 :                 if (r < 0)
    2879           0 :                         return r;
    2880             : 
    2881           0 :                 copy = strdup(j);
    2882           0 :                 if (!copy)
    2883           0 :                         return -ENOMEM;
    2884             : 
    2885           0 :                 *job = copy;
    2886             :         }
    2887             : 
    2888           0 :         return 1;
    2889             : }
    2890             : 
    2891           0 : int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) {
    2892           0 :         _cleanup_free_ char *path = NULL;
    2893             :         int r;
    2894             : 
    2895           0 :         assert(manager);
    2896           0 :         assert(scope);
    2897             : 
    2898           0 :         path = unit_dbus_path_from_name(scope);
    2899           0 :         if (!path)
    2900           0 :                 return -ENOMEM;
    2901             : 
    2902           0 :         r = sd_bus_call_method(
    2903             :                         manager->bus,
    2904             :                         "org.freedesktop.systemd1",
    2905             :                         path,
    2906             :                         "org.freedesktop.systemd1.Scope",
    2907             :                         "Abandon",
    2908             :                         error,
    2909             :                         NULL,
    2910             :                         NULL);
    2911           0 :         if (r < 0) {
    2912           0 :                 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
    2913           0 :                     sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) ||
    2914           0 :                     sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) {
    2915           0 :                         sd_bus_error_free(error);
    2916           0 :                         return 0;
    2917             :                 }
    2918             : 
    2919           0 :                 return r;
    2920             :         }
    2921             : 
    2922           0 :         return 1;
    2923             : }
    2924             : 
    2925           0 : int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
    2926           0 :         assert(manager);
    2927           0 :         assert(unit);
    2928             : 
    2929           0 :         return sd_bus_call_method(
    2930             :                         manager->bus,
    2931             :                         "org.freedesktop.systemd1",
    2932             :                         "/org/freedesktop/systemd1",
    2933             :                         "org.freedesktop.systemd1.Manager",
    2934             :                         "KillUnit",
    2935             :                         error,
    2936             :                         NULL,
    2937             :                         "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
    2938             : }
    2939             : 
    2940           0 : int manager_unit_is_active(Manager *manager, const char *unit) {
    2941           0 :         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
    2942           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    2943           0 :         _cleanup_free_ char *path = NULL;
    2944             :         const char *state;
    2945             :         int r;
    2946             : 
    2947           0 :         assert(manager);
    2948           0 :         assert(unit);
    2949             : 
    2950           0 :         path = unit_dbus_path_from_name(unit);
    2951           0 :         if (!path)
    2952           0 :                 return -ENOMEM;
    2953             : 
    2954           0 :         r = sd_bus_get_property(
    2955             :                         manager->bus,
    2956             :                         "org.freedesktop.systemd1",
    2957             :                         path,
    2958             :                         "org.freedesktop.systemd1.Unit",
    2959             :                         "ActiveState",
    2960             :                         &error,
    2961             :                         &reply,
    2962             :                         "s");
    2963           0 :         if (r < 0) {
    2964             :                 /* systemd might have droppped off momentarily, let's
    2965             :                  * not make this an error */
    2966           0 :                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
    2967           0 :                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
    2968           0 :                         return true;
    2969             : 
    2970             :                 /* If the unit is already unloaded then it's not
    2971             :                  * active */
    2972           0 :                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
    2973           0 :                     sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
    2974           0 :                         return false;
    2975             : 
    2976           0 :                 return r;
    2977             :         }
    2978             : 
    2979           0 :         r = sd_bus_message_read(reply, "s", &state);
    2980           0 :         if (r < 0)
    2981           0 :                 return -EINVAL;
    2982             : 
    2983           0 :         return !streq(state, "inactive") && !streq(state, "failed");
    2984             : }
    2985             : 
    2986           0 : int manager_job_is_active(Manager *manager, const char *path) {
    2987           0 :         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
    2988           0 :         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
    2989             :         int r;
    2990             : 
    2991           0 :         assert(manager);
    2992           0 :         assert(path);
    2993             : 
    2994           0 :         r = sd_bus_get_property(
    2995             :                         manager->bus,
    2996             :                         "org.freedesktop.systemd1",
    2997             :                         path,
    2998             :                         "org.freedesktop.systemd1.Job",
    2999             :                         "State",
    3000             :                         &error,
    3001             :                         &reply,
    3002             :                         "s");
    3003           0 :         if (r < 0) {
    3004           0 :                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
    3005           0 :                     sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
    3006           0 :                         return true;
    3007             : 
    3008           0 :                 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
    3009           0 :                         return false;
    3010             : 
    3011           0 :                 return r;
    3012             :         }
    3013             : 
    3014             :         /* We don't actually care about the state really. The fact
    3015             :          * that we could read the job state is enough for us */
    3016             : 
    3017           0 :         return true;
    3018             : }

Generated by: LCOV version 1.11