LCOV - code coverage report
Current view: top level - core - dbus-scope.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 4 131 3.1 %
Date: 2019-08-23 13:36:53 Functions: 1 8 12.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 136 1.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "alloc-util.h"
       4                 :            : #include "bus-common-errors.h"
       5                 :            : #include "bus-internal.h"
       6                 :            : #include "bus-util.h"
       7                 :            : #include "dbus-cgroup.h"
       8                 :            : #include "dbus-kill.h"
       9                 :            : #include "dbus-scope.h"
      10                 :            : #include "dbus-unit.h"
      11                 :            : #include "dbus-util.h"
      12                 :            : #include "dbus.h"
      13                 :            : #include "scope.h"
      14                 :            : #include "selinux-access.h"
      15                 :            : #include "unit.h"
      16                 :            : 
      17                 :          0 : int bus_scope_method_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
      18                 :          0 :         Scope *s = userdata;
      19                 :            :         int r;
      20                 :            : 
      21         [ #  # ]:          0 :         assert(message);
      22         [ #  # ]:          0 :         assert(s);
      23                 :            : 
      24         [ #  # ]:          0 :         r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
      25         [ #  # ]:          0 :         if (r < 0)
      26                 :          0 :                 return r;
      27                 :            : 
      28         [ #  # ]:          0 :         r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
      29         [ #  # ]:          0 :         if (r < 0)
      30                 :          0 :                 return r;
      31         [ #  # ]:          0 :         if (r == 0)
      32                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
      33                 :            : 
      34                 :          0 :         r = scope_abandon(s);
      35         [ #  # ]:          0 :         if (r == -ESTALE)
      36         [ #  # ]:          0 :                 return sd_bus_error_setf(error, BUS_ERROR_SCOPE_NOT_RUNNING, "Scope %s is not running, cannot abandon.", UNIT(s)->id);
      37         [ #  # ]:          0 :         if (r < 0)
      38                 :          0 :                 return r;
      39                 :            : 
      40                 :          0 :         return sd_bus_reply_method_return(message, NULL);
      41                 :            : }
      42                 :            : 
      43   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
                   #  # ]
      44                 :            : 
      45                 :            : const sd_bus_vtable bus_scope_vtable[] = {
      46                 :            :         SD_BUS_VTABLE_START(0),
      47                 :            :         SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
      48                 :            :         SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
      49                 :            :         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
      50                 :            :         SD_BUS_SIGNAL("RequestStop", NULL, 0),
      51                 :            :         SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_method_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
      52                 :            :         SD_BUS_VTABLE_END
      53                 :            : };
      54                 :            : 
      55                 :          0 : static int bus_scope_set_transient_property(
      56                 :            :                 Scope *s,
      57                 :            :                 const char *name,
      58                 :            :                 sd_bus_message *message,
      59                 :            :                 UnitWriteFlags flags,
      60                 :            :                 sd_bus_error *error) {
      61                 :            : 
      62                 :            :         int r;
      63                 :            : 
      64         [ #  # ]:          0 :         assert(s);
      65         [ #  # ]:          0 :         assert(name);
      66         [ #  # ]:          0 :         assert(message);
      67                 :            : 
      68                 :          0 :         flags |= UNIT_PRIVATE;
      69                 :            : 
      70         [ #  # ]:          0 :         if (streq(name, "TimeoutStopUSec"))
      71         [ #  # ]:          0 :                 return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error);
      72                 :            : 
      73         [ #  # ]:          0 :         if (streq(name, "PIDs")) {
      74                 :          0 :                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
      75                 :          0 :                 unsigned n = 0;
      76                 :            : 
      77                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "u");
      78         [ #  # ]:          0 :                 if (r < 0)
      79                 :          0 :                         return r;
      80                 :            : 
      81                 :          0 :                 for (;;) {
      82                 :            :                         uint32_t upid;
      83                 :            :                         pid_t pid;
      84                 :            : 
      85                 :          0 :                         r = sd_bus_message_read(message, "u", &upid);
      86         [ #  # ]:          0 :                         if (r < 0)
      87                 :          0 :                                 return r;
      88         [ #  # ]:          0 :                         if (r == 0)
      89                 :          0 :                                 break;
      90                 :            : 
      91         [ #  # ]:          0 :                         if (upid == 0) {
      92         [ #  # ]:          0 :                                 if (!creds) {
      93                 :          0 :                                         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
      94         [ #  # ]:          0 :                                         if (r < 0)
      95                 :          0 :                                                 return r;
      96                 :            :                                 }
      97                 :            : 
      98                 :          0 :                                 r = sd_bus_creds_get_pid(creds, &pid);
      99         [ #  # ]:          0 :                                 if (r < 0)
     100                 :          0 :                                         return r;
     101                 :            :                         } else
     102                 :          0 :                                 pid = (uid_t) upid;
     103                 :            : 
     104         [ #  # ]:          0 :                         r = unit_pid_attachable(UNIT(s), pid, error);
     105         [ #  # ]:          0 :                         if (r < 0)
     106                 :          0 :                                 return r;
     107                 :            : 
     108         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     109         [ #  # ]:          0 :                                 r = unit_watch_pid(UNIT(s), pid, false);
     110   [ #  #  #  # ]:          0 :                                 if (r < 0 && r != -EEXIST)
     111                 :          0 :                                         return r;
     112                 :            :                         }
     113                 :            : 
     114                 :          0 :                         n++;
     115                 :            :                 }
     116                 :            : 
     117                 :          0 :                 r = sd_bus_message_exit_container(message);
     118         [ #  # ]:          0 :                 if (r < 0)
     119                 :          0 :                         return r;
     120                 :            : 
     121         [ #  # ]:          0 :                 if (n <= 0)
     122                 :          0 :                         return -EINVAL;
     123                 :            : 
     124                 :          0 :                 return 1;
     125                 :            : 
     126         [ #  # ]:          0 :         } else if (streq(name, "Controller")) {
     127                 :            :                 const char *controller;
     128                 :            : 
     129                 :            :                 /* We can't support direct connections with this, as direct connections know no service or unique name
     130                 :            :                  * concept, but the Controller field stores exactly that. */
     131   [ #  #  #  # ]:          0 :                 if (sd_bus_message_get_bus(message) != UNIT(s)->manager->api_bus)
     132                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Sorry, Controller= logic only supported via the bus.");
     133                 :            : 
     134                 :          0 :                 r = sd_bus_message_read(message, "s", &controller);
     135         [ #  # ]:          0 :                 if (r < 0)
     136                 :          0 :                         return r;
     137                 :            : 
     138   [ #  #  #  # ]:          0 :                 if (!isempty(controller) && !service_name_is_valid(controller))
     139                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
     140                 :            : 
     141         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     142                 :          0 :                         r = free_and_strdup(&s->controller, empty_to_null(controller));
     143         [ #  # ]:          0 :                         if (r < 0)
     144                 :          0 :                                 return r;
     145                 :            :                 }
     146                 :            : 
     147                 :          0 :                 return 1;
     148                 :            :         }
     149                 :            : 
     150                 :          0 :         return 0;
     151                 :            : }
     152                 :            : 
     153                 :          0 : int bus_scope_set_property(
     154                 :            :                 Unit *u,
     155                 :            :                 const char *name,
     156                 :            :                 sd_bus_message *message,
     157                 :            :                 UnitWriteFlags flags,
     158                 :            :                 sd_bus_error *error) {
     159                 :            : 
     160                 :          0 :         Scope *s = SCOPE(u);
     161                 :            :         int r;
     162                 :            : 
     163         [ #  # ]:          0 :         assert(s);
     164         [ #  # ]:          0 :         assert(name);
     165         [ #  # ]:          0 :         assert(message);
     166                 :            : 
     167                 :          0 :         r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
     168         [ #  # ]:          0 :         if (r != 0)
     169                 :          0 :                 return r;
     170                 :            : 
     171         [ #  # ]:          0 :         if (u->load_state == UNIT_STUB) {
     172                 :            :                 /* While we are created we still accept PIDs */
     173                 :            : 
     174                 :          0 :                 r = bus_scope_set_transient_property(s, name, message, flags, error);
     175         [ #  # ]:          0 :                 if (r != 0)
     176                 :          0 :                         return r;
     177                 :            : 
     178                 :          0 :                 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error);
     179         [ #  # ]:          0 :                 if (r != 0)
     180                 :          0 :                         return r;
     181                 :            :         }
     182                 :            : 
     183                 :          0 :         return 0;
     184                 :            : }
     185                 :            : 
     186                 :          0 : int bus_scope_commit_properties(Unit *u) {
     187         [ #  # ]:          0 :         assert(u);
     188                 :            : 
     189                 :          0 :         unit_invalidate_cgroup_members_masks(u);
     190                 :          0 :         unit_realize_cgroup(u);
     191                 :            : 
     192                 :          0 :         return 0;
     193                 :            : }
     194                 :            : 
     195                 :          0 : int bus_scope_send_request_stop(Scope *s) {
     196                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
     197                 :          0 :         _cleanup_free_ char *p = NULL;
     198                 :            :         int r;
     199                 :            : 
     200         [ #  # ]:          0 :         assert(s);
     201                 :            : 
     202         [ #  # ]:          0 :         if (!s->controller)
     203                 :          0 :                 return 0;
     204                 :            : 
     205         [ #  # ]:          0 :         p = unit_dbus_path(UNIT(s));
     206         [ #  # ]:          0 :         if (!p)
     207                 :          0 :                 return -ENOMEM;
     208                 :            : 
     209                 :          0 :         r = sd_bus_message_new_signal(
     210         [ #  # ]:          0 :                         UNIT(s)->manager->api_bus,
     211                 :            :                         &m,
     212                 :            :                         p,
     213                 :            :                         "org.freedesktop.systemd1.Scope",
     214                 :            :                         "RequestStop");
     215         [ #  # ]:          0 :         if (r < 0)
     216                 :          0 :                 return r;
     217                 :            : 
     218         [ #  # ]:          0 :         return sd_bus_send_to(UNIT(s)->manager->api_bus, m, s->controller, NULL);
     219                 :            : }
     220                 :            : 
     221                 :          0 : static int on_controller_gone(sd_bus_track *track, void *userdata) {
     222                 :          0 :         Scope *s = userdata;
     223                 :            : 
     224         [ #  # ]:          0 :         assert(track);
     225                 :            : 
     226         [ #  # ]:          0 :         if (s->controller) {
     227   [ #  #  #  # ]:          0 :                 log_unit_debug(UNIT(s), "Controller %s disappeared from bus.", s->controller);
     228         [ #  # ]:          0 :                 unit_add_to_dbus_queue(UNIT(s));
     229                 :          0 :                 s->controller = mfree(s->controller);
     230                 :            :         }
     231                 :            : 
     232                 :          0 :         s->controller_track = sd_bus_track_unref(s->controller_track);
     233                 :            : 
     234                 :          0 :         return 0;
     235                 :            : }
     236                 :            : 
     237                 :         44 : int bus_scope_track_controller(Scope *s) {
     238                 :            :         int r;
     239                 :            : 
     240         [ -  + ]:         44 :         assert(s);
     241                 :            : 
     242   [ -  +  #  # ]:         44 :         if (!s->controller || s->controller_track)
     243                 :         44 :                 return 0;
     244                 :            : 
     245         [ #  # ]:          0 :         r = sd_bus_track_new(UNIT(s)->manager->api_bus, &s->controller_track, on_controller_gone, s);
     246         [ #  # ]:          0 :         if (r < 0)
     247                 :          0 :                 return r;
     248                 :            : 
     249                 :          0 :         r = sd_bus_track_add_name(s->controller_track, s->controller);
     250         [ #  # ]:          0 :         if (r < 0) {
     251                 :          0 :                 s->controller_track = sd_bus_track_unref(s->controller_track);
     252                 :          0 :                 return r;
     253                 :            :         }
     254                 :            : 
     255                 :          0 :         return 0;
     256                 :            : }

Generated by: LCOV version 1.14