]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-scope.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / dbus-scope.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
6c12b52e
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
b5efdb8a 21#include "alloc-util.h"
96aad8d1 22#include "bus-common-errors.h"
b5efdb8a
LP
23#include "bus-internal.h"
24#include "bus-util.h"
1d22e906
LP
25#include "dbus-cgroup.h"
26#include "dbus-kill.h"
27#include "dbus-scope.h"
b5efdb8a
LP
28#include "dbus-unit.h"
29#include "dbus.h"
30#include "scope.h"
31#include "selinux-access.h"
32#include "unit.h"
6c12b52e 33
19070062 34static int bus_scope_abandon(sd_bus_message *message, void *userdata, sd_bus_error *error) {
a911bb9a 35 Scope *s = userdata;
4e2f8d27 36 int r;
a911bb9a 37
a911bb9a
LP
38 assert(message);
39 assert(s);
40
1d22e906
LP
41 r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
42 if (r < 0)
43 return r;
44
45 r = bus_verify_manage_units_async(UNIT(s)->manager, message, error);
283868e1
SW
46 if (r < 0)
47 return r;
48 if (r == 0)
49 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
50
4e2f8d27 51 r = scope_abandon(s);
4e2f8d27
LP
52 if (r == -ESTALE)
53 return sd_bus_error_setf(error, BUS_ERROR_SCOPE_NOT_RUNNING, "Scope %s is not running, cannot abandon.", UNIT(s)->id);
1d22e906
LP
54 if (r < 0)
55 return r;
4e2f8d27
LP
56
57 return sd_bus_reply_method_return(message, NULL);
a911bb9a
LP
58}
59
718db961 60static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
6c12b52e 61
718db961
LP
62const sd_bus_vtable bus_scope_vtable[] = {
63 SD_BUS_VTABLE_START(0),
2d4a39e7 64 SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 65 SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
718db961 66 SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2d4a39e7 67 SD_BUS_SIGNAL("RequestStop", NULL, 0),
1d22e906 68 SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
718db961
LP
69 SD_BUS_VTABLE_END
70};
6c12b52e 71
9f2e86af 72static int bus_scope_set_transient_property(
6c12b52e
LP
73 Scope *s,
74 const char *name,
718db961 75 sd_bus_message *message,
6c12b52e 76 UnitSetPropertiesMode mode,
718db961 77 sd_bus_error *error) {
6c12b52e
LP
78
79 int r;
80
6c12b52e 81 assert(s);
718db961
LP
82 assert(name);
83 assert(message);
6c12b52e
LP
84
85 if (streq(name, "PIDs")) {
294a90cc 86 unsigned n = 0;
718db961 87 uint32_t pid;
6c12b52e 88
718db961
LP
89 r = sd_bus_message_enter_container(message, 'a', "u");
90 if (r < 0)
91 return r;
6c12b52e 92
718db961 93 while ((r = sd_bus_message_read(message, "u", &pid)) > 0) {
6c12b52e
LP
94
95 if (pid <= 1)
96 return -EINVAL;
97
adb3a45d 98 if (mode != UNIT_CHECK) {
a911bb9a 99 r = unit_watch_pid(UNIT(s), pid);
adb3a45d
LP
100 if (r < 0 && r != -EEXIST)
101 return r;
102 }
6c12b52e 103
adb3a45d 104 n++;
6c12b52e 105 }
718db961
LP
106 if (r < 0)
107 return r;
108
109 r = sd_bus_message_exit_container(message);
110 if (r < 0)
111 return r;
6c12b52e 112
adb3a45d 113 if (n <= 0)
6c12b52e
LP
114 return -EINVAL;
115
116 return 1;
cc23f9f1 117
2d4a39e7
LP
118 } else if (streq(name, "Controller")) {
119 const char *controller;
120 char *c;
121
122 r = sd_bus_message_read(message, "s", &controller);
123 if (r < 0)
124 return r;
125
126 if (!isempty(controller) && !service_name_is_valid(controller))
127 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller);
128
129 if (mode != UNIT_CHECK) {
130 if (isempty(controller))
131 c = NULL;
132 else {
133 c = strdup(controller);
134 if (!c)
135 return -ENOMEM;
136 }
137
138 free(s->controller);
139 s->controller = c;
140 }
141
142 return 1;
143
cc23f9f1
LP
144 } else if (streq(name, "TimeoutStopUSec")) {
145
cc23f9f1 146 if (mode != UNIT_CHECK) {
718db961
LP
147 r = sd_bus_message_read(message, "t", &s->timeout_stop_usec);
148 if (r < 0)
149 return r;
150
b27b4b51 151 unit_write_drop_in_private_format(UNIT(s), mode, name, "TimeoutStopSec="USEC_FMT"us", s->timeout_stop_usec);
718db961
LP
152 } else {
153 r = sd_bus_message_skip(message, "t");
154 if (r < 0)
155 return r;
cc23f9f1
LP
156 }
157
158 return 1;
6c12b52e
LP
159 }
160
161 return 0;
162}
163
164int bus_scope_set_property(
165 Unit *u,
166 const char *name,
718db961 167 sd_bus_message *message,
6c12b52e 168 UnitSetPropertiesMode mode,
718db961 169 sd_bus_error *error) {
6c12b52e
LP
170
171 Scope *s = SCOPE(u);
172 int r;
173
718db961 174 assert(s);
6c12b52e 175 assert(name);
718db961 176 assert(message);
6c12b52e 177
718db961 178 r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
6c12b52e
LP
179 if (r != 0)
180 return r;
181
182 if (u->load_state == UNIT_STUB) {
183 /* While we are created we still accept PIDs */
184
718db961 185 r = bus_scope_set_transient_property(s, name, message, mode, error);
6c12b52e
LP
186 if (r != 0)
187 return r;
a6c0353b 188
718db961 189 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
a6c0353b
LP
190 if (r != 0)
191 return r;
6c12b52e
LP
192 }
193
194 return 0;
195}
196
197int bus_scope_commit_properties(Unit *u) {
198 assert(u);
199
bc432dc7 200 unit_update_cgroup_members_masks(u);
6c12b52e 201 unit_realize_cgroup(u);
bc432dc7 202
6c12b52e
LP
203 return 0;
204}
2d4a39e7
LP
205
206int bus_scope_send_request_stop(Scope *s) {
4afd3348 207 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2d4a39e7
LP
208 _cleanup_free_ char *p = NULL;
209 int r;
210
211 assert(s);
212
213 if (!s->controller)
214 return 0;
215
216 p = unit_dbus_path(UNIT(s));
217 if (!p)
218 return -ENOMEM;
219
220 r = sd_bus_message_new_signal(
221 UNIT(s)->manager->api_bus,
151b9b96 222 &m,
2d4a39e7
LP
223 p,
224 "org.freedesktop.systemd1.Scope",
151b9b96 225 "RequestStop");
2d4a39e7
LP
226 if (r < 0)
227 return r;
228
f4b0fb23 229 return sd_bus_send_to(UNIT(s)->manager->api_bus, m, s->controller, NULL);
2d4a39e7 230}