6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering/***
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering This file is part of systemd.
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering Copyright 2013 Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering systemd is free software; you can redistribute it and/or modify it
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering under the terms of the GNU Lesser General Public License as published by
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering (at your option) any later version.
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering systemd is distributed in the hope that it will be useful, but
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering Lesser General Public License for more details.
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering You should have received a copy of the GNU Lesser General Public License
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering***/
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
96aad8d15a324d0e956a4e5653a11a67b209b41aLennart Poettering#include "bus-common-errors.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "bus-internal.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "bus-util.h"
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering#include "dbus-cgroup.h"
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering#include "dbus-kill.h"
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering#include "dbus-scope.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "dbus-unit.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "dbus.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "scope.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "selinux-access.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "unit.h"
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_scope_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering Scope *s = userdata;
4e2f8d27781731021aa6b96c0ee18a8966eefe1cLennart Poettering int r;
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering assert(message);
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering assert(s);
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering if (r < 0)
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering return r;
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
283868e1dcd8ea7475850d9c6e7d4722c473dd50Stef Walter if (r < 0)
283868e1dcd8ea7475850d9c6e7d4722c473dd50Stef Walter return r;
283868e1dcd8ea7475850d9c6e7d4722c473dd50Stef Walter if (r == 0)
283868e1dcd8ea7475850d9c6e7d4722c473dd50Stef Walter return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
283868e1dcd8ea7475850d9c6e7d4722c473dd50Stef Walter
4e2f8d27781731021aa6b96c0ee18a8966eefe1cLennart Poettering r = scope_abandon(s);
4e2f8d27781731021aa6b96c0ee18a8966eefe1cLennart Poettering if (r == -ESTALE)
4e2f8d27781731021aa6b96c0ee18a8966eefe1cLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_SCOPE_NOT_RUNNING, "Scope %s is not running, cannot abandon.", UNIT(s)->id);
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering if (r < 0)
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering return r;
4e2f8d27781731021aa6b96c0ee18a8966eefe1cLennart Poettering
4e2f8d27781731021aa6b96c0ee18a8966eefe1cLennart Poettering return sd_bus_reply_method_return(message, NULL);
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering}
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poetteringstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poetteringconst sd_bus_vtable bus_scope_vtable[] = {
718db96199eb307751264e4163555662c9a389faLennart Poettering SD_BUS_VTABLE_START(0),
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc57b10a12a03edd3d3e90ca17398ad206Lennart Poettering SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
718db96199eb307751264e4163555662c9a389faLennart Poettering SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering SD_BUS_SIGNAL("RequestStop", NULL, 0),
1d22e9068c52c1cf935bcdff70b9b9654e3c939eLennart Poettering SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
718db96199eb307751264e4163555662c9a389faLennart Poettering SD_BUS_VTABLE_END
718db96199eb307751264e4163555662c9a389faLennart Poettering};
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poetteringstatic int bus_scope_set_transient_property(
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering Scope *s,
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering const char *name,
718db96199eb307751264e4163555662c9a389faLennart Poettering sd_bus_message *message,
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering UnitSetPropertiesMode mode,
718db96199eb307751264e4163555662c9a389faLennart Poettering sd_bus_error *error) {
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering int r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering assert(s);
718db96199eb307751264e4163555662c9a389faLennart Poettering assert(name);
718db96199eb307751264e4163555662c9a389faLennart Poettering assert(message);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (streq(name, "PIDs")) {
294a90cc4af5139e936975a38baaa62771af96baDave Reisner unsigned n = 0;
718db96199eb307751264e4163555662c9a389faLennart Poettering uint32_t pid;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering r = sd_bus_message_enter_container(message, 'a', "u");
718db96199eb307751264e4163555662c9a389faLennart Poettering if (r < 0)
718db96199eb307751264e4163555662c9a389faLennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering while ((r = sd_bus_message_read(message, "u", &pid)) > 0) {
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (pid <= 1)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return -EINVAL;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
adb3a45d9a1cebdec30406cc2c04503fc5e735beLennart Poettering if (mode != UNIT_CHECK) {
a911bb9ab27ac0eb3bbf4e8b4109e5da9b88eee3Lennart Poettering r = unit_watch_pid(UNIT(s), pid);
adb3a45d9a1cebdec30406cc2c04503fc5e735beLennart Poettering if (r < 0 && r != -EEXIST)
adb3a45d9a1cebdec30406cc2c04503fc5e735beLennart Poettering return r;
adb3a45d9a1cebdec30406cc2c04503fc5e735beLennart Poettering }
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
adb3a45d9a1cebdec30406cc2c04503fc5e735beLennart Poettering n++;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering }
718db96199eb307751264e4163555662c9a389faLennart Poettering if (r < 0)
718db96199eb307751264e4163555662c9a389faLennart Poettering return r;
718db96199eb307751264e4163555662c9a389faLennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering r = sd_bus_message_exit_container(message);
718db96199eb307751264e4163555662c9a389faLennart Poettering if (r < 0)
718db96199eb307751264e4163555662c9a389faLennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
adb3a45d9a1cebdec30406cc2c04503fc5e735beLennart Poettering if (n <= 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return -EINVAL;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return 1;
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering } else if (streq(name, "Controller")) {
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering const char *controller;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering char *c;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering r = sd_bus_message_read(message, "s", &controller);
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (r < 0)
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return r;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (!isempty(controller) && !service_name_is_valid(controller))
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (mode != UNIT_CHECK) {
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (isempty(controller))
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering c = NULL;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering else {
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering c = strdup(controller);
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (!c)
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return -ENOMEM;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering }
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering free(s->controller);
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering s->controller = c;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering }
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return 1;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering } else if (streq(name, "TimeoutStopUSec")) {
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering if (mode != UNIT_CHECK) {
718db96199eb307751264e4163555662c9a389faLennart Poettering r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
718db96199eb307751264e4163555662c9a389faLennart Poettering if (r < 0)
718db96199eb307751264e4163555662c9a389faLennart Poettering return r;
718db96199eb307751264e4163555662c9a389faLennart Poettering
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec="USEC_FMT"us\n", s->timeout_stop_usec);
718db96199eb307751264e4163555662c9a389faLennart Poettering } else {
718db96199eb307751264e4163555662c9a389faLennart Poettering r = sd_bus_message_skip(message, "t");
718db96199eb307751264e4163555662c9a389faLennart Poettering if (r < 0)
718db96199eb307751264e4163555662c9a389faLennart Poettering return r;
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering }
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering
cc23f9f17434aad3941dff3c20bce485b39ce47cLennart Poettering return 1;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering }
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return 0;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering}
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poetteringint bus_scope_set_property(
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering Unit *u,
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering const char *name,
718db96199eb307751264e4163555662c9a389faLennart Poettering sd_bus_message *message,
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering UnitSetPropertiesMode mode,
718db96199eb307751264e4163555662c9a389faLennart Poettering sd_bus_error *error) {
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering Scope *s = SCOPE(u);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering int r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering assert(s);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering assert(name);
718db96199eb307751264e4163555662c9a389faLennart Poettering assert(message);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (r != 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (u->load_state == UNIT_STUB) {
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering /* While we are created we still accept PIDs */
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering r = bus_scope_set_transient_property(s, name, message, mode, error);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (r != 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return r;
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering
718db96199eb307751264e4163555662c9a389faLennart Poettering r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering if (r != 0)
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering }
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return 0;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering}
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poetteringint bus_scope_commit_properties(Unit *u) {
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering assert(u);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
bc432dc7eb62c5671f2b741a86a66393adb350dcLennart Poettering unit_update_cgroup_members_masks(u);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering unit_realize_cgroup(u);
bc432dc7eb62c5671f2b741a86a66393adb350dcLennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return 0;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering}
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poetteringint bus_scope_send_request_stop(Scope *s) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering _cleanup_free_ char *p = NULL;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering int r;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering assert(s);
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (!s->controller)
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return 0;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering p = unit_dbus_path(UNIT(s));
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (!p)
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return -ENOMEM;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering r = sd_bus_message_new_signal(
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering UNIT(s)->manager->api_bus,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering &m,
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering p,
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering "org.freedesktop.systemd1.Scope",
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering "RequestStop");
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering if (r < 0)
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return r;
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering return sd_bus_send_to(UNIT(s)->manager->api_bus, m, /* s->controller */ NULL, NULL);
2d4a39e759c4ab846ad8a546abeddd40bc8d736eLennart Poettering}