]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-manager.c
core: add a concept of "dynamic" user ids, that are allocated as long as a service...
[thirdparty/systemd.git] / src / core / dbus-manager.c
CommitLineData
a7334b09
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 14 Lesser General Public License for more details.
a7334b09 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
ea430986 20#include <errno.h>
eed67a30 21#include <sys/prctl.h>
871c44a7 22#include <unistd.h>
ea430986 23
b5efdb8a 24#include "alloc-util.h"
07630cea 25#include "architecture.h"
09bde77f 26#include "build.h"
07630cea 27#include "bus-common-errors.h"
24efb112 28#include "clock-util.h"
07630cea 29#include "dbus-execute.h"
2ea31e5b 30#include "dbus-job.h"
3ffd4af2 31#include "dbus-manager.h"
07630cea
LP
32#include "dbus-unit.h"
33#include "dbus.h"
34#include "env-util.h"
3ffd4af2 35#include "fd-util.h"
0d39fa9c 36#include "fileio.h"
6482f626 37#include "formats-util.h"
07630cea
LP
38#include "install.h"
39#include "log.h"
40#include "path-util.h"
41#include "selinux-access.h"
8fcde012 42#include "stat-util.h"
07630cea
LP
43#include "string-util.h"
44#include "strv.h"
7ccbd1ae 45#include "syslog-util.h"
29206d46 46#include "user-util.h"
07630cea
LP
47#include "virt.h"
48#include "watchdog.h"
ea430986 49
718db961
LP
50static int property_get_version(
51 sd_bus *bus,
52 const char *path,
53 const char *interface,
54 const char *property,
55 sd_bus_message *reply,
ebcf1f97
LP
56 void *userdata,
57 sd_bus_error *error) {
718db961
LP
58
59 assert(bus);
60 assert(reply);
61
62 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
63}
c5d34390 64
718db961
LP
65static int property_get_features(
66 sd_bus *bus,
67 const char *path,
68 const char *interface,
69 const char *property,
70 sd_bus_message *reply,
ebcf1f97
LP
71 void *userdata,
72 sd_bus_error *error) {
718db961
LP
73
74 assert(bus);
75 assert(reply);
76
77 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
78}
79
80static int property_get_virtualization(
81 sd_bus *bus,
82 const char *path,
83 const char *interface,
84 const char *property,
85 sd_bus_message *reply,
ebcf1f97
LP
86 void *userdata,
87 sd_bus_error *error) {
718db961 88
5c22925a
LP
89 int v;
90
718db961
LP
91 assert(bus);
92 assert(reply);
93
5c22925a
LP
94 v = detect_virtualization();
95
96 /* Make sure to return the empty string when we detect no virtualization, as that is the API.
97 *
98 * https://github.com/systemd/systemd/issues/1423
99 */
100
101 return sd_bus_message_append(
102 reply, "s",
103 v == VIRTUALIZATION_NONE ? "" : virtualization_to_string(v));
718db961
LP
104}
105
7452394e
LP
106static int property_get_architecture(
107 sd_bus *bus,
108 const char *path,
109 const char *interface,
110 const char *property,
111 sd_bus_message *reply,
112 void *userdata,
113 sd_bus_error *error) {
114
115 assert(bus);
116 assert(reply);
117
118 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
119}
120
718db961
LP
121static int property_get_tainted(
122 sd_bus *bus,
123 const char *path,
124 const char *interface,
125 const char *property,
126 sd_bus_message *reply,
ebcf1f97
LP
127 void *userdata,
128 sd_bus_error *error) {
718db961 129
b492ce8a 130 char buf[sizeof("split-usr:cgroups-missing:local-hwclock:")] = "", *e = buf;
718db961
LP
131 Manager *m = userdata;
132
133 assert(bus);
134 assert(reply);
bfebab7f 135 assert(m);
c5d34390 136
72bc8d00 137 if (m->taint_usr)
e677bf7e 138 e = stpcpy(e, "split-usr:");
c5d34390 139
871c44a7 140 if (access("/proc/cgroups", F_OK) < 0)
1ebf0cb7 141 e = stpcpy(e, "cgroups-missing:");
871c44a7 142
6369641d 143 if (clock_is_localtime(NULL) > 0)
1ebf0cb7 144 e = stpcpy(e, "local-hwclock:");
e677bf7e 145
1ebf0cb7
MS
146 /* remove the last ':' */
147 if (e != buf)
148 e[-1] = 0;
e677bf7e 149
718db961 150 return sd_bus_message_append(reply, "s", buf);
c5d34390
LP
151}
152
718db961
LP
153static int property_get_log_target(
154 sd_bus *bus,
155 const char *path,
156 const char *interface,
157 const char *property,
158 sd_bus_message *reply,
ebcf1f97
LP
159 void *userdata,
160 sd_bus_error *error) {
1adf1049 161
718db961
LP
162 assert(bus);
163 assert(reply);
1adf1049 164
718db961 165 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
1adf1049
LP
166}
167
718db961
LP
168static int property_set_log_target(
169 sd_bus *bus,
170 const char *path,
171 const char *interface,
172 const char *property,
173 sd_bus_message *value,
ebcf1f97
LP
174 void *userdata,
175 sd_bus_error *error) {
718db961 176
c826cda4 177 const char *t;
718db961 178 int r;
c826cda4 179
718db961
LP
180 assert(bus);
181 assert(value);
c826cda4 182
718db961
LP
183 r = sd_bus_message_read(value, "s", &t);
184 if (r < 0)
185 return r;
c826cda4
AB
186
187 return log_set_target_from_string(t);
188}
189
718db961
LP
190static int property_get_log_level(
191 sd_bus *bus,
192 const char *path,
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
ebcf1f97
LP
196 void *userdata,
197 sd_bus_error *error) {
718db961 198
68eda4bd 199 _cleanup_free_ char *t = NULL;
f8b69d1d 200 int r;
1adf1049 201
718db961
LP
202 assert(bus);
203 assert(reply);
1adf1049 204
f8b69d1d
MS
205 r = log_level_to_string_alloc(log_get_max_level(), &t);
206 if (r < 0)
207 return r;
1adf1049 208
718db961 209 return sd_bus_message_append(reply, "s", t);
1adf1049
LP
210}
211
718db961
LP
212static int property_set_log_level(
213 sd_bus *bus,
214 const char *path,
215 const char *interface,
216 const char *property,
217 sd_bus_message *value,
ebcf1f97
LP
218 void *userdata,
219 sd_bus_error *error) {
718db961 220
c826cda4 221 const char *t;
718db961 222 int r;
c826cda4 223
718db961
LP
224 assert(bus);
225 assert(value);
c826cda4 226
718db961
LP
227 r = sd_bus_message_read(value, "s", &t);
228 if (r < 0)
229 return r;
c826cda4 230
4cee3a78
ZJS
231 r = log_set_max_level_from_string(t);
232 if (r == 0)
233 log_info("Setting log level to %s.", t);
234 return r;
c826cda4
AB
235}
236
718db961
LP
237static int property_get_n_names(
238 sd_bus *bus,
239 const char *path,
240 const char *interface,
241 const char *property,
242 sd_bus_message *reply,
ebcf1f97
LP
243 void *userdata,
244 sd_bus_error *error) {
4f0f902f 245
718db961 246 Manager *m = userdata;
4f0f902f 247
718db961
LP
248 assert(bus);
249 assert(reply);
250 assert(m);
4f0f902f 251
718db961 252 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
4f0f902f
LP
253}
254
f755e3b7
LP
255static int property_get_n_failed_units(
256 sd_bus *bus,
257 const char *path,
258 const char *interface,
259 const char *property,
260 sd_bus_message *reply,
261 void *userdata,
262 sd_bus_error *error) {
263
264 Manager *m = userdata;
265
266 assert(bus);
267 assert(reply);
268 assert(m);
269
270 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
271}
272
718db961
LP
273static int property_get_n_jobs(
274 sd_bus *bus,
275 const char *path,
276 const char *interface,
277 const char *property,
278 sd_bus_message *reply,
ebcf1f97
LP
279 void *userdata,
280 sd_bus_error *error) {
4f0f902f 281
718db961 282 Manager *m = userdata;
4f0f902f 283
718db961
LP
284 assert(bus);
285 assert(reply);
286 assert(m);
4f0f902f 287
718db961 288 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
4f0f902f
LP
289}
290
718db961
LP
291static int property_get_progress(
292 sd_bus *bus,
293 const char *path,
294 const char *interface,
295 const char *property,
296 sd_bus_message *reply,
ebcf1f97
LP
297 void *userdata,
298 sd_bus_error *error) {
718db961
LP
299
300 Manager *m = userdata;
05d6a3b6
LP
301 double d;
302
718db961
LP
303 assert(bus);
304 assert(reply);
bfebab7f 305 assert(m);
05d6a3b6
LP
306
307 if (dual_timestamp_is_set(&m->finish_timestamp))
308 d = 1.0;
309 else
310 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
311
718db961
LP
312 return sd_bus_message_append(reply, "d", d);
313}
314
f755e3b7
LP
315static int property_get_system_state(
316 sd_bus *bus,
317 const char *path,
318 const char *interface,
319 const char *property,
320 sd_bus_message *reply,
321 void *userdata,
322 sd_bus_error *error) {
323
324 Manager *m = userdata;
325
326 assert(bus);
327 assert(reply);
328 assert(m);
329
330 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
331}
332
718db961
LP
333static int property_set_runtime_watchdog(
334 sd_bus *bus,
335 const char *path,
336 const char *interface,
337 const char *property,
338 sd_bus_message *value,
ebcf1f97
LP
339 void *userdata,
340 sd_bus_error *error) {
05d6a3b6 341
718db961
LP
342 usec_t *t = userdata;
343 int r;
344
345 assert(bus);
346 assert(value);
347
348 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
349
350 r = sd_bus_message_read(value, "t", t);
351 if (r < 0)
352 return r;
353
354 return watchdog_set_timeout(t);
05d6a3b6
LP
355}
356
eed67a30
EV
357static int property_get_timer_slack_nsec(
358 sd_bus *bus,
359 const char *path,
360 const char *interface,
361 const char *property,
362 sd_bus_message *reply,
363 void *userdata,
364 sd_bus_error *error) {
365
366 assert(bus);
367 assert(reply);
368
369 return sd_bus_message_append(reply, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
370}
371
19070062 372static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
373 _cleanup_free_ char *path = NULL;
374 Manager *m = userdata;
375 const char *name;
376 Unit *u;
377 int r;
dfae3488 378
718db961 379 assert(message);
dfae3488
LP
380 assert(m);
381
283868e1
SW
382 /* Anyone can call this method */
383
718db961
LP
384 r = sd_bus_message_read(message, "s", &name);
385 if (r < 0)
ebcf1f97 386 return r;
dfae3488 387
1d22e906 388 if (isempty(name)) {
4afd3348 389 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1d22e906
LP
390 pid_t pid;
391
392 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
393 if (r < 0)
394 return r;
395
396 r = sd_bus_creds_get_pid(creds, &pid);
397 if (r < 0)
398 return r;
399
400 u = manager_get_unit_by_pid(m, pid);
401 if (!u)
402 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
403 } else {
404 u = manager_get_unit(m, name);
405 if (!u)
406 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
407 }
dfae3488 408
8a188de9 409 r = mac_selinux_unit_access_check(u, message, "status", error);
ebcf1f97
LP
410 if (r < 0)
411 return r;
dfae3488 412
718db961
LP
413 path = unit_dbus_path(u);
414 if (!path)
ebcf1f97 415 return -ENOMEM;
729e3769 416
df2d202e 417 return sd_bus_reply_method_return(message, "o", path);
718db961 418}
c0576cd6 419
19070062 420static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
421 _cleanup_free_ char *path = NULL;
422 Manager *m = userdata;
423 pid_t pid;
424 Unit *u;
425 int r;
c0576cd6 426
718db961
LP
427 assert(message);
428 assert(m);
c0576cd6 429
718db961 430 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
729e3769 431
283868e1
SW
432 /* Anyone can call this method */
433
718db961
LP
434 r = sd_bus_message_read(message, "u", &pid);
435 if (r < 0)
ebcf1f97 436 return r;
1d22e906
LP
437 if (pid < 0)
438 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
718db961
LP
439
440 if (pid == 0) {
4afd3348 441 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
5b12334d
LP
442
443 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
444 if (r < 0)
445 return r;
446
447 r = sd_bus_creds_get_pid(creds, &pid);
718db961 448 if (r < 0)
ebcf1f97 449 return r;
729e3769
LP
450 }
451
718db961
LP
452 u = manager_get_unit_by_pid(m, pid);
453 if (!u)
1fa2f38f 454 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
c0576cd6 455
8a188de9 456 r = mac_selinux_unit_access_check(u, message, "status", error);
ebcf1f97
LP
457 if (r < 0)
458 return r;
718db961
LP
459
460 path = unit_dbus_path(u);
461 if (!path)
ebcf1f97 462 return -ENOMEM;
718db961 463
df2d202e 464 return sd_bus_reply_method_return(message, "o", path);
718db961
LP
465}
466
19070062 467static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
468 _cleanup_free_ char *path = NULL;
469 Manager *m = userdata;
470 const char *name;
471 Unit *u;
472 int r;
c0576cd6 473
718db961
LP
474 assert(message);
475 assert(m);
476
283868e1
SW
477 /* Anyone can call this method */
478
718db961
LP
479 r = sd_bus_message_read(message, "s", &name);
480 if (r < 0)
ebcf1f97 481 return r;
c0576cd6 482
1d22e906 483 if (isempty(name)) {
4afd3348 484 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1d22e906
LP
485 pid_t pid;
486
487 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
488 if (r < 0)
489 return r;
490
491 r = sd_bus_creds_get_pid(creds, &pid);
492 if (r < 0)
493 return r;
494
495 u = manager_get_unit_by_pid(m, pid);
496 if (!u)
497 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
498 } else {
499 r = manager_load_unit(m, name, NULL, error, &u);
500 if (r < 0)
501 return r;
502 }
718db961 503
8a188de9 504 r = mac_selinux_unit_access_check(u, message, "status", error);
ebcf1f97
LP
505 if (r < 0)
506 return r;
c0576cd6 507
718db961
LP
508 path = unit_dbus_path(u);
509 if (!path)
ebcf1f97 510 return -ENOMEM;
718db961 511
df2d202e 512 return sd_bus_reply_method_return(message, "o", path);
c0576cd6
LP
513}
514
19070062 515static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
718db961
LP
516 const char *name;
517 Unit *u;
c0576cd6
LP
518 int r;
519
718db961
LP
520 assert(message);
521 assert(m);
c0576cd6 522
718db961
LP
523 r = sd_bus_message_read(message, "s", &name);
524 if (r < 0)
ebcf1f97 525 return r;
c0576cd6 526
ebcf1f97 527 r = manager_load_unit(m, name, NULL, error, &u);
718db961 528 if (r < 0)
ebcf1f97 529 return r;
718db961 530
19070062 531 return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
c0576cd6
LP
532}
533
19070062
LP
534static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
535 return method_start_unit_generic(message, userdata, JOB_START, false, error);
718db961 536}
c757a65b 537
19070062
LP
538static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
539 return method_start_unit_generic(message, userdata, JOB_STOP, false, error);
718db961 540}
c757a65b 541
19070062
LP
542static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
543 return method_start_unit_generic(message, userdata, JOB_RELOAD, false, error);
718db961 544}
c757a65b 545
19070062
LP
546static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
547 return method_start_unit_generic(message, userdata, JOB_RESTART, false, error);
c757a65b
LP
548}
549
19070062
LP
550static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
551 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, false, error);
718db961 552}
d200735e 553
19070062
LP
554static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
555 return method_start_unit_generic(message, userdata, JOB_RESTART, true, error);
718db961 556}
d200735e 557
19070062
LP
558static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
559 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, true, error);
718db961 560}
d200735e 561
19070062 562static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
563 Manager *m = userdata;
564 const char *old_name;
565 Unit *u;
1adf1049 566 int r;
ea430986 567
ea430986
LP
568 assert(message);
569 assert(m);
570
718db961
LP
571 r = sd_bus_message_read(message, "s", &old_name);
572 if (r < 0)
ebcf1f97 573 return r;
ea430986 574
718db961
LP
575 u = manager_get_unit(m, old_name);
576 if (!u || !u->job || u->job->type != JOB_START)
ebcf1f97 577 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
c0576cd6 578
19070062 579 return method_start_unit_generic(message, m, JOB_START, false, error);
718db961 580}
ea430986 581
19070062 582static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
583 Manager *m = userdata;
584 const char *name;
585 Unit *u;
586 int r;
ea430986 587
718db961
LP
588 assert(message);
589 assert(m);
ea430986 590
718db961
LP
591 r = sd_bus_message_read(message, "s", &name);
592 if (r < 0)
ebcf1f97 593 return r;
598b557b 594
718db961
LP
595 u = manager_get_unit(m, name);
596 if (!u)
ebcf1f97 597 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
0a524ba7 598
19070062 599 return bus_unit_method_kill(message, u, error);
718db961 600}
8a0867d6 601
19070062 602static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
603 Manager *m = userdata;
604 const char *name;
605 Unit *u;
606 int r;
8a0867d6 607
718db961
LP
608 assert(message);
609 assert(m);
cad45ba1 610
718db961
LP
611 r = sd_bus_message_read(message, "s", &name);
612 if (r < 0)
ebcf1f97 613 return r;
ea430986 614
718db961
LP
615 u = manager_get_unit(m, name);
616 if (!u)
ebcf1f97 617 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
5dd9014f 618
19070062 619 return bus_unit_method_reset_failed(message, u, error);
718db961 620}
5dd9014f 621
19070062 622static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
623 Manager *m = userdata;
624 const char *name;
625 Unit *u;
626 int r;
5dd9014f 627
718db961
LP
628 assert(message);
629 assert(m);
630
631 r = sd_bus_message_read(message, "s", &name);
632 if (r < 0)
ebcf1f97 633 return r;
718db961 634
e9fd88f2
FB
635 r = manager_load_unit(m, name, NULL, error, &u);
636 if (r < 0)
637 return r;
638
639 r = bus_unit_check_load_state(u, error);
640 if (r < 0)
641 return r;
ea430986 642
19070062 643 return bus_unit_method_set_properties(message, u, error);
718db961
LP
644}
645
6900c740 646static int reply_unit_info(sd_bus_message *reply, Unit *u) {
647 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
648 Unit *following;
649
650 following = unit_following(u);
651
652 unit_path = unit_dbus_path(u);
653 if (!unit_path)
654 return -ENOMEM;
655
656 if (u->job) {
657 job_path = job_dbus_path(u->job);
658 if (!job_path)
659 return -ENOMEM;
660 }
661
662 return sd_bus_message_append(
663 reply, "(ssssssouso)",
664 u->id,
665 unit_description(u),
666 unit_load_state_to_string(u->load_state),
667 unit_active_state_to_string(unit_active_state(u)),
668 unit_sub_state_to_string(u),
669 following ? following->id : "",
670 unit_path,
671 u->job ? u->job->id : 0,
672 u->job ? job_type_to_string(u->job->type) : "",
673 job_path ? job_path : "/");
674}
675
676static int method_list_units_by_names(sd_bus_message *message, void *userdata, sd_bus_error *error) {
677 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
678 Manager *m = userdata;
679 int r;
680 char **unit;
681 _cleanup_strv_free_ char **units = NULL;
682
683 assert(message);
684 assert(m);
685
686 r = sd_bus_message_read_strv(message, &units);
687 if (r < 0)
688 return r;
689
690 r = sd_bus_message_new_method_return(message, &reply);
691 if (r < 0)
692 return r;
693
694 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
695 if (r < 0)
696 return r;
697
698 STRV_FOREACH(unit, units) {
699 Unit *u;
700
701 if (!unit_name_is_valid(*unit, UNIT_NAME_ANY))
702 continue;
703
704 r = manager_load_unit(m, *unit, NULL, error, &u);
705 if (r < 0)
706 return r;
707
708 r = reply_unit_info(reply, u);
709 if (r < 0)
710 return r;
711 }
712
713 r = sd_bus_message_close_container(reply);
714 if (r < 0)
715 return r;
716
717 return sd_bus_send(NULL, reply, NULL);
718}
719
291d565a
LP
720static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
721 Manager *m = userdata;
722 const char *name;
723 Unit *u;
724 int r;
725
726 assert(message);
727 assert(m);
728
729 r = sd_bus_message_read(message, "s", &name);
730 if (r < 0)
731 return r;
732
733 r = manager_load_unit(m, name, NULL, error, &u);
734 if (r < 0)
735 return r;
736
737 r = bus_unit_check_load_state(u, error);
738 if (r < 0)
739 return r;
740
741 return bus_unit_method_get_processes(message, u, error);
742}
743
ab31f6b8
WC
744static int transient_unit_from_message(
745 Manager *m,
746 sd_bus_message *message,
747 const char *name,
748 Unit **unit,
749 sd_bus_error *error) {
750
06cc6afa 751 UnitType t;
ab31f6b8
WC
752 Unit *u;
753 int r;
754
755 assert(m);
756 assert(message);
757 assert(name);
758
06cc6afa
LP
759 t = unit_name_to_type(name);
760 if (t < 0)
761 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name or type.");
762
763 if (!unit_vtable[t]->can_transient)
764 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
765
ab31f6b8
WC
766 r = manager_load_unit(m, name, NULL, error, &u);
767 if (r < 0)
768 return r;
769
0f13f3bd 770 if (!unit_is_pristine(u))
ab31f6b8
WC
771 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
772
773 /* OK, the unit failed to load and is unreferenced, now let's
774 * fill in the transient data instead */
775 r = unit_make_transient(u);
776 if (r < 0)
777 return r;
778
779 /* Set our properties */
780 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
781 if (r < 0)
782 return r;
783
97329d20 784 /* Now load the missing bits of the unit we just created */
4f952a3f 785 unit_add_to_load_queue(u);
97329d20
LP
786 manager_dispatch_load_queue(m);
787
ab31f6b8
WC
788 *unit = u;
789
790 return 0;
791}
792
793static int transient_aux_units_from_message(
794 Manager *m,
795 sd_bus_message *message,
796 sd_bus_error *error) {
797
ab31f6b8
WC
798 int r;
799
800 assert(m);
801 assert(message);
802
803 r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
804 if (r < 0)
805 return r;
806
807 while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
97329d20
LP
808 const char *name = NULL;
809 Unit *u;
810
ab31f6b8
WC
811 r = sd_bus_message_read(message, "s", &name);
812 if (r < 0)
813 return r;
814
815 r = transient_unit_from_message(m, message, name, &u, error);
97329d20 816 if (r < 0)
ab31f6b8
WC
817 return r;
818
ab31f6b8
WC
819 r = sd_bus_message_exit_container(message);
820 if (r < 0)
821 return r;
822 }
823 if (r < 0)
824 return r;
825
826 r = sd_bus_message_exit_container(message);
827 if (r < 0)
828 return r;
829
830 return 0;
831}
832
19070062 833static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
834 const char *name, *smode;
835 Manager *m = userdata;
836 JobMode mode;
718db961
LP
837 Unit *u;
838 int r;
ea430986 839
718db961
LP
840 assert(message);
841 assert(m);
ea430986 842
1d22e906 843 r = mac_selinux_access_check(message, "start", error);
283868e1
SW
844 if (r < 0)
845 return r;
283868e1 846
718db961
LP
847 r = sd_bus_message_read(message, "ss", &name, &smode);
848 if (r < 0)
ebcf1f97 849 return r;
5632e374 850
718db961
LP
851 mode = job_mode_from_string(smode);
852 if (mode < 0)
ebcf1f97 853 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
5632e374 854
1d22e906 855 r = bus_verify_manage_units_async(m, message, error);
718db961 856 if (r < 0)
ebcf1f97 857 return r;
1d22e906
LP
858 if (r == 0)
859 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
5632e374 860
ab31f6b8 861 r = transient_unit_from_message(m, message, name, &u, error);
ebcf1f97
LP
862 if (r < 0)
863 return r;
5632e374 864
ab31f6b8 865 r = transient_aux_units_from_message(m, message, error);
718db961 866 if (r < 0)
ebcf1f97 867 return r;
ea430986 868
718db961 869 /* Finally, start it */
19070062 870 return bus_unit_queue_job(message, u, JOB_START, mode, false, error);
718db961 871}
ea430986 872
19070062 873static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
874 _cleanup_free_ char *path = NULL;
875 Manager *m = userdata;
876 uint32_t id;
877 Job *j;
878 int r;
ea430986 879
718db961
LP
880 assert(message);
881 assert(m);
ea430986 882
283868e1
SW
883 /* Anyone can call this method */
884
718db961
LP
885 r = sd_bus_message_read(message, "u", &id);
886 if (r < 0)
ebcf1f97 887 return r;
ea430986 888
718db961
LP
889 j = manager_get_job(m, id);
890 if (!j)
ebcf1f97 891 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
ea430986 892
8a188de9 893 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
ebcf1f97
LP
894 if (r < 0)
895 return r;
ea430986 896
718db961
LP
897 path = job_dbus_path(j);
898 if (!path)
ebcf1f97 899 return -ENOMEM;
ea430986 900
df2d202e 901 return sd_bus_reply_method_return(message, "o", path);
718db961 902}
ea430986 903
19070062 904static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
905 Manager *m = userdata;
906 uint32_t id;
907 Job *j;
908 int r;
ea430986 909
718db961
LP
910 assert(message);
911 assert(m);
ea430986 912
718db961
LP
913 r = sd_bus_message_read(message, "u", &id);
914 if (r < 0)
ebcf1f97 915 return r;
ea430986 916
718db961
LP
917 j = manager_get_job(m, id);
918 if (!j)
ebcf1f97 919 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
ea430986 920
19070062 921 return bus_job_method_cancel(message, j, error);
718db961 922}
c1e1601e 923
19070062 924static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 925 Manager *m = userdata;
ebcf1f97 926 int r;
c1e1601e 927
718db961
LP
928 assert(message);
929 assert(m);
c1e1601e 930
1d22e906 931 r = mac_selinux_access_check(message, "reload", error);
ebcf1f97
LP
932 if (r < 0)
933 return r;
934
1d22e906
LP
935 r = bus_verify_manage_units_async(m, message, error);
936 if (r < 0)
937 return r;
938 if (r == 0)
939 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
940
718db961 941 manager_clear_jobs(m);
c1e1601e 942
df2d202e 943 return sd_bus_reply_method_return(message, NULL);
718db961 944}
c1e1601e 945
19070062 946static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 947 Manager *m = userdata;
ebcf1f97 948 int r;
cad45ba1 949
718db961
LP
950 assert(message);
951 assert(m);
952
8a188de9 953 r = mac_selinux_access_check(message, "reload", error);
ebcf1f97
LP
954 if (r < 0)
955 return r;
956
1d22e906
LP
957 r = bus_verify_manage_units_async(m, message, error);
958 if (r < 0)
959 return r;
960 if (r == 0)
961 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
962
718db961 963 manager_reset_failed(m);
c1e1601e 964
df2d202e 965 return sd_bus_reply_method_return(message, NULL);
718db961 966}
c1e1601e 967
313fe66f 968static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
4afd3348 969 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
718db961
LP
970 Manager *m = userdata;
971 const char *k;
972 Iterator i;
973 Unit *u;
974 int r;
c1e1601e 975
718db961
LP
976 assert(message);
977 assert(m);
b152adec 978
283868e1
SW
979 /* Anyone can call this method */
980
8a188de9 981 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
982 if (r < 0)
983 return r;
cad45ba1 984
df2d202e 985 r = sd_bus_message_new_method_return(message, &reply);
718db961 986 if (r < 0)
ebcf1f97 987 return r;
b152adec 988
718db961
LP
989 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
990 if (r < 0)
ebcf1f97 991 return r;
b152adec 992
718db961 993 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
718db961
LP
994 if (k != u->id)
995 continue;
b152adec 996
cdc06ed7
DS
997 if (!strv_isempty(states) &&
998 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
999 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
1000 !strv_contains(states, unit_sub_state_to_string(u)))
1001 continue;
1002
313fe66f 1003 if (!strv_isempty(patterns) &&
1004 !strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
1005 continue;
1006
6900c740 1007 r = reply_unit_info(reply, u);
718db961 1008 if (r < 0)
ebcf1f97 1009 return r;
718db961 1010 }
4139c1b2 1011
718db961
LP
1012 r = sd_bus_message_close_container(reply);
1013 if (r < 0)
ebcf1f97 1014 return r;
cad45ba1 1015
9030ca46 1016 return sd_bus_send(NULL, reply, NULL);
718db961 1017}
4139c1b2 1018
19070062 1019static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
313fe66f 1020 return list_units_filtered(message, userdata, error, NULL, NULL);
cdc06ed7
DS
1021}
1022
19070062 1023static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cdc06ed7
DS
1024 _cleanup_strv_free_ char **states = NULL;
1025 int r;
1026
1027 r = sd_bus_message_read_strv(message, &states);
1028 if (r < 0)
1029 return r;
1030
313fe66f 1031 return list_units_filtered(message, userdata, error, states, NULL);
1032}
1033
1034static int method_list_units_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1035 _cleanup_strv_free_ char **states = NULL;
1036 _cleanup_strv_free_ char **patterns = NULL;
1037 int r;
1038
1039 r = sd_bus_message_read_strv(message, &states);
1040 if (r < 0)
1041 return r;
1042
1043 r = sd_bus_message_read_strv(message, &patterns);
1044 if (r < 0)
1045 return r;
1046
1047 return list_units_filtered(message, userdata, error, states, patterns);
cdc06ed7
DS
1048}
1049
19070062 1050static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
4afd3348 1051 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
718db961
LP
1052 Manager *m = userdata;
1053 Iterator i;
1054 Job *j;
1055 int r;
4139c1b2 1056
718db961
LP
1057 assert(message);
1058 assert(m);
1059
283868e1
SW
1060 /* Anyone can call this method */
1061
8a188de9 1062 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1063 if (r < 0)
1064 return r;
718db961 1065
df2d202e 1066 r = sd_bus_message_new_method_return(message, &reply);
718db961 1067 if (r < 0)
ebcf1f97 1068 return r;
718db961
LP
1069
1070 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
1071 if (r < 0)
ebcf1f97 1072 return r;
718db961
LP
1073
1074 HASHMAP_FOREACH(j, m->jobs, i) {
1075 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
1076
1077 job_path = job_dbus_path(j);
1078 if (!job_path)
ebcf1f97 1079 return -ENOMEM;
718db961
LP
1080
1081 unit_path = unit_dbus_path(j->unit);
1082 if (!unit_path)
ebcf1f97 1083 return -ENOMEM;
718db961
LP
1084
1085 r = sd_bus_message_append(
1086 reply, "(usssoo)",
1087 j->id,
1302759d 1088 j->unit->id,
718db961 1089 job_type_to_string(j->type),
1302759d 1090 job_state_to_string(j->state),
718db961
LP
1091 job_path,
1092 unit_path);
cad45ba1 1093 if (r < 0)
ebcf1f97 1094 return r;
718db961 1095 }
5dd9014f 1096
718db961
LP
1097 r = sd_bus_message_close_container(reply);
1098 if (r < 0)
ebcf1f97 1099 return r;
5dd9014f 1100
9030ca46 1101 return sd_bus_send(NULL, reply, NULL);
718db961 1102}
5dd9014f 1103
19070062 1104static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1105 Manager *m = userdata;
1106 int r;
5dd9014f 1107
718db961
LP
1108 assert(message);
1109 assert(m);
ea430986 1110
283868e1
SW
1111 /* Anyone can call this method */
1112
8a188de9 1113 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1114 if (r < 0)
1115 return r;
cad45ba1 1116
19070062 1117 if (sd_bus_message_get_bus(message) == m->api_bus) {
8f8f05a9
LP
1118
1119 /* Note that direct bus connection subscribe by
1120 * default, we only track peers on the API bus here */
1121
1122 if (!m->subscribed) {
19070062 1123 r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
8f8f05a9
LP
1124 if (r < 0)
1125 return r;
1126 }
1127
1128 r = sd_bus_track_add_sender(m->subscribed, message);
1129 if (r < 0)
1130 return r;
1131 if (r == 0)
1132 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1133 }
ea430986 1134
df2d202e 1135 return sd_bus_reply_method_return(message, NULL);
718db961 1136}
ea430986 1137
19070062 1138static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1139 Manager *m = userdata;
1140 int r;
ea430986 1141
718db961
LP
1142 assert(message);
1143 assert(m);
ea430986 1144
283868e1
SW
1145 /* Anyone can call this method */
1146
8a188de9 1147 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1148 if (r < 0)
1149 return r;
ea430986 1150
19070062 1151 if (sd_bus_message_get_bus(message) == m->api_bus) {
8f8f05a9
LP
1152 r = sd_bus_track_remove_sender(m->subscribed, message);
1153 if (r < 0)
1154 return r;
1155 if (r == 0)
1156 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1157 }
ea430986 1158
df2d202e 1159 return sd_bus_reply_method_return(message, NULL);
718db961 1160}
ea430986 1161
19070062 1162static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1163 _cleanup_free_ char *dump = NULL;
1164 _cleanup_fclose_ FILE *f = NULL;
1165 Manager *m = userdata;
1166 size_t size;
ebcf1f97 1167 int r;
ea430986 1168
718db961
LP
1169 assert(message);
1170 assert(m);
ea430986 1171
283868e1
SW
1172 /* Anyone can call this method */
1173
8a188de9 1174 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1175 if (r < 0)
1176 return r;
ea430986 1177
718db961
LP
1178 f = open_memstream(&dump, &size);
1179 if (!f)
ebcf1f97 1180 return -ENOMEM;
ea430986 1181
718db961
LP
1182 manager_dump_units(m, f, NULL);
1183 manager_dump_jobs(m, f, NULL);
ea430986 1184
dacd6cee
LP
1185 r = fflush_and_check(f);
1186 if (r < 0)
1187 return r;
a16e1123 1188
df2d202e 1189 return sd_bus_reply_method_return(message, "s", dump);
718db961 1190}
cad45ba1 1191
36b4a7ba
ZJS
1192static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1193 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
718db961 1194}
cad45ba1 1195
19070062 1196static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1197 Manager *m = userdata;
1198 int r;
6652a2b9 1199
718db961
LP
1200 assert(message);
1201 assert(m);
6652a2b9 1202
1d22e906 1203 r = mac_selinux_access_check(message, "reload", error);
283868e1
SW
1204 if (r < 0)
1205 return r;
283868e1 1206
1d22e906 1207 r = bus_verify_reload_daemon_async(m, message, error);
ebcf1f97
LP
1208 if (r < 0)
1209 return r;
1d22e906
LP
1210 if (r == 0)
1211 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
6652a2b9 1212
718db961
LP
1213 /* Instead of sending the reply back right away, we just
1214 * remember that we need to and then send it after the reload
1215 * is finished. That way the caller knows when the reload
1216 * finished. */
6652a2b9 1217
718db961 1218 assert(!m->queued_message);
df2d202e 1219 r = sd_bus_message_new_method_return(message, &m->queued_message);
718db961 1220 if (r < 0)
ebcf1f97 1221 return r;
cad45ba1 1222
718db961 1223 m->exit_code = MANAGER_RELOAD;
6652a2b9 1224
718db961
LP
1225 return 1;
1226}
6652a2b9 1227
19070062 1228static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 1229 Manager *m = userdata;
ebcf1f97 1230 int r;
6652a2b9 1231
718db961
LP
1232 assert(message);
1233 assert(m);
6652a2b9 1234
1d22e906 1235 r = mac_selinux_access_check(message, "reload", error);
283868e1
SW
1236 if (r < 0)
1237 return r;
283868e1 1238
1d22e906 1239 r = bus_verify_reload_daemon_async(m, message, error);
ebcf1f97
LP
1240 if (r < 0)
1241 return r;
1d22e906
LP
1242 if (r == 0)
1243 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
cad45ba1 1244
718db961
LP
1245 /* We don't send a reply back here, the client should
1246 * just wait for us disconnecting. */
6652a2b9 1247
718db961
LP
1248 m->exit_code = MANAGER_REEXECUTE;
1249 return 1;
1250}
6652a2b9 1251
19070062 1252static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 1253 Manager *m = userdata;
ebcf1f97 1254 int r;
6652a2b9 1255
718db961
LP
1256 assert(message);
1257 assert(m);
6652a2b9 1258
8a188de9 1259 r = mac_selinux_access_check(message, "halt", error);
ebcf1f97
LP
1260 if (r < 0)
1261 return r;
cad45ba1 1262
287419c1
AC
1263 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1264 * we are running on the host. It will fall back on reboot() in
1265 * systemd-shutdown if it cannot do the exit() because it isn't a
1266 * container. */
6652a2b9 1267
718db961 1268 m->exit_code = MANAGER_EXIT;
6652a2b9 1269
df2d202e 1270 return sd_bus_reply_method_return(message, NULL);
718db961 1271}
6652a2b9 1272
19070062 1273static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 1274 Manager *m = userdata;
ebcf1f97 1275 int r;
664f88a7 1276
718db961
LP
1277 assert(message);
1278 assert(m);
cad45ba1 1279
8a188de9 1280 r = mac_selinux_access_check(message, "reboot", error);
ebcf1f97
LP
1281 if (r < 0)
1282 return r;
664f88a7 1283
463d0d15 1284 if (!MANAGER_IS_SYSTEM(m))
ebcf1f97 1285 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
664f88a7 1286
718db961 1287 m->exit_code = MANAGER_REBOOT;
664f88a7 1288
df2d202e 1289 return sd_bus_reply_method_return(message, NULL);
718db961 1290}
664f88a7 1291
19070062 1292static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 1293 Manager *m = userdata;
ebcf1f97 1294 int r;
50913bc0 1295
718db961
LP
1296 assert(message);
1297 assert(m);
1137a57c 1298
8a188de9 1299 r = mac_selinux_access_check(message, "halt", error);
ebcf1f97
LP
1300 if (r < 0)
1301 return r;
1137a57c 1302
463d0d15 1303 if (!MANAGER_IS_SYSTEM(m))
ebcf1f97 1304 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1137a57c 1305
718db961 1306 m->exit_code = MANAGER_POWEROFF;
1137a57c 1307
df2d202e 1308 return sd_bus_reply_method_return(message, NULL);
718db961 1309}
1137a57c 1310
19070062 1311static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 1312 Manager *m = userdata;
ebcf1f97 1313 int r;
1137a57c 1314
718db961
LP
1315 assert(message);
1316 assert(m);
8d0e38a2 1317
8a188de9 1318 r = mac_selinux_access_check(message, "halt", error);
ebcf1f97
LP
1319 if (r < 0)
1320 return r;
cad45ba1 1321
463d0d15 1322 if (!MANAGER_IS_SYSTEM(m))
ebcf1f97 1323 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
8d0e38a2 1324
718db961 1325 m->exit_code = MANAGER_HALT;
8d0e38a2 1326
df2d202e 1327 return sd_bus_reply_method_return(message, NULL);
718db961 1328}
8d0e38a2 1329
19070062 1330static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 1331 Manager *m = userdata;
ebcf1f97 1332 int r;
8d0e38a2 1333
718db961
LP
1334 assert(message);
1335 assert(m);
c0576cd6 1336
8a188de9 1337 r = mac_selinux_access_check(message, "reboot", error);
ebcf1f97
LP
1338 if (r < 0)
1339 return r;
cad45ba1 1340
463d0d15 1341 if (!MANAGER_IS_SYSTEM(m))
ebcf1f97 1342 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
c0576cd6 1343
718db961 1344 m->exit_code = MANAGER_KEXEC;
c0576cd6 1345
df2d202e 1346 return sd_bus_reply_method_return(message, NULL);
718db961 1347}
c0576cd6 1348
19070062 1349static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1350 char *ri = NULL, *rt = NULL;
1351 const char *root, *init;
1352 Manager *m = userdata;
1353 int r;
c0576cd6 1354
718db961
LP
1355 assert(message);
1356 assert(m);
c0576cd6 1357
8a188de9 1358 r = mac_selinux_access_check(message, "reboot", error);
ebcf1f97
LP
1359 if (r < 0)
1360 return r;
c0576cd6 1361
463d0d15 1362 if (!MANAGER_IS_SYSTEM(m))
6ad3b2b6 1363 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
c0576cd6 1364
718db961
LP
1365 r = sd_bus_message_read(message, "ss", &root, &init);
1366 if (r < 0)
ebcf1f97 1367 return r;
c0576cd6 1368
718db961 1369 if (path_equal(root, "/") || !path_is_absolute(root))
ebcf1f97 1370 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
c0576cd6 1371
718db961
LP
1372 /* Safety check */
1373 if (isempty(init)) {
6ad3b2b6 1374 if (!path_is_os_tree(root))
5ae4d543 1375 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
718db961
LP
1376 } else {
1377 _cleanup_free_ char *p = NULL;
c0576cd6 1378
718db961 1379 if (!path_is_absolute(init))
ebcf1f97 1380 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
c0576cd6 1381
718db961
LP
1382 p = strappend(root, init);
1383 if (!p)
ebcf1f97 1384 return -ENOMEM;
c0576cd6 1385
718db961 1386 if (access(p, X_OK) < 0)
ebcf1f97 1387 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
718db961
LP
1388 }
1389
1390 rt = strdup(root);
1391 if (!rt)
ebcf1f97 1392 return -ENOMEM;
718db961
LP
1393
1394 if (!isempty(init)) {
1395 ri = strdup(init);
1396 if (!ri) {
92b315df 1397 free(rt);
ebcf1f97 1398 return -ENOMEM;
c0576cd6 1399 }
718db961 1400 }
c0576cd6 1401
718db961
LP
1402 free(m->switch_root);
1403 m->switch_root = rt;
c0576cd6 1404
718db961
LP
1405 free(m->switch_root_init);
1406 m->switch_root_init = ri;
c0576cd6 1407
92b315df
LP
1408 m->exit_code = MANAGER_SWITCH_ROOT;
1409
df2d202e 1410 return sd_bus_reply_method_return(message, NULL);
718db961 1411}
c0576cd6 1412
19070062 1413static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1414 _cleanup_strv_free_ char **plus = NULL;
1415 Manager *m = userdata;
1416 int r;
c0576cd6 1417
718db961
LP
1418 assert(message);
1419 assert(m);
cad45ba1 1420
8a188de9 1421 r = mac_selinux_access_check(message, "reload", error);
ebcf1f97
LP
1422 if (r < 0)
1423 return r;
c0576cd6 1424
718db961
LP
1425 r = sd_bus_message_read_strv(message, &plus);
1426 if (r < 0)
ebcf1f97 1427 return r;
718db961 1428 if (!strv_env_is_valid(plus))
ebcf1f97 1429 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
c0576cd6 1430
1d22e906
LP
1431 r = bus_verify_set_environment_async(m, message, error);
1432 if (r < 0)
1433 return r;
1434 if (r == 0)
1435 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1436
718db961
LP
1437 r = manager_environment_add(m, NULL, plus);
1438 if (r < 0)
ebcf1f97 1439 return r;
c0576cd6 1440
df2d202e 1441 return sd_bus_reply_method_return(message, NULL);
718db961
LP
1442}
1443
19070062 1444static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1445 _cleanup_strv_free_ char **minus = NULL;
1446 Manager *m = userdata;
1447 int r;
1448
718db961
LP
1449 assert(message);
1450 assert(m);
1451
8a188de9 1452 r = mac_selinux_access_check(message, "reload", error);
ebcf1f97
LP
1453 if (r < 0)
1454 return r;
c0576cd6 1455
718db961
LP
1456 r = sd_bus_message_read_strv(message, &minus);
1457 if (r < 0)
ebcf1f97 1458 return r;
718db961
LP
1459
1460 if (!strv_env_name_or_assignment_is_valid(minus))
ebcf1f97 1461 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
718db961 1462
1d22e906
LP
1463 r = bus_verify_set_environment_async(m, message, error);
1464 if (r < 0)
1465 return r;
1466 if (r == 0)
1467 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1468
718db961
LP
1469 r = manager_environment_add(m, minus, NULL);
1470 if (r < 0)
ebcf1f97 1471 return r;
718db961 1472
df2d202e 1473 return sd_bus_reply_method_return(message, NULL);
718db961
LP
1474}
1475
19070062 1476static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1477 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1478 Manager *m = userdata;
1479 int r;
1480
718db961
LP
1481 assert(message);
1482 assert(m);
1483
8a188de9 1484 r = mac_selinux_access_check(message, "reload", error);
ebcf1f97
LP
1485 if (r < 0)
1486 return r;
718db961 1487
eb6c7d20 1488 r = sd_bus_message_read_strv(message, &minus);
718db961 1489 if (r < 0)
ebcf1f97 1490 return r;
718db961 1491
eb6c7d20 1492 r = sd_bus_message_read_strv(message, &plus);
718db961 1493 if (r < 0)
ebcf1f97 1494 return r;
718db961 1495
718db961 1496 if (!strv_env_name_or_assignment_is_valid(minus))
ebcf1f97 1497 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
eb6c7d20
ZJS
1498 if (!strv_env_is_valid(plus))
1499 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
718db961 1500
1d22e906
LP
1501 r = bus_verify_set_environment_async(m, message, error);
1502 if (r < 0)
1503 return r;
1504 if (r == 0)
1505 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1506
718db961
LP
1507 r = manager_environment_add(m, minus, plus);
1508 if (r < 0)
ebcf1f97 1509 return r;
718db961 1510
df2d202e 1511 return sd_bus_reply_method_return(message, NULL);
718db961
LP
1512}
1513
287419c1 1514static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
287419c1 1515 Manager *m = userdata;
29206d46 1516 uint8_t code;
287419c1
AC
1517 int r;
1518
1519 assert(message);
1520 assert(m);
1521
1522 r = mac_selinux_access_check(message, "exit", error);
1523 if (r < 0)
1524 return r;
1525
1526 r = sd_bus_message_read_basic(message, 'y', &code);
1527 if (r < 0)
1528 return r;
1529
463d0d15 1530 if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
287419c1
AC
1531 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
1532
1533 m->return_value = code;
1534
1535 return sd_bus_reply_method_return(message, NULL);
1536}
1537
29206d46
LP
1538static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1539 Manager *m = userdata;
1540 const char *name;
1541 uid_t uid;
1542 int r;
1543
1544 assert(message);
1545 assert(m);
1546
1547 r = sd_bus_message_read_basic(message, 's', &name);
1548 if (r < 0)
1549 return r;
1550
1551 if (!MANAGER_IS_SYSTEM(m))
1552 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
1553 if (!valid_user_group_name(name))
1554 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User name invalid: %s", name);
1555
1556 r = dynamic_user_lookup_name(m, name, &uid);
1557 if (r == -ESRCH)
1558 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER, "Dynamic user %s does not exist.", name);
1559 if (r < 0)
1560 return r;
1561
1562 return sd_bus_reply_method_return(message, "u", (uint32_t) uid);
1563}
1564
1565static int method_lookup_dynamic_user_by_uid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1566 _cleanup_free_ char *name = NULL;
1567 Manager *m = userdata;
1568 uid_t uid;
1569 int r;
1570
1571 assert(message);
1572 assert(m);
1573
1574 assert_cc(sizeof(uid) == sizeof(uint32_t));
1575 r = sd_bus_message_read_basic(message, 'u', &uid);
1576 if (r < 0)
1577 return r;
1578
1579 if (!MANAGER_IS_SYSTEM(m))
1580 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
1581 if (!uid_is_valid(uid))
1582 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User ID invalid: " UID_FMT, uid);
1583
1584 r = dynamic_user_lookup_uid(m, uid, &name);
1585 if (r == -ESRCH)
1586 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER, "Dynamic user ID " UID_FMT " does not exist.", uid);
1587 if (r < 0)
1588 return r;
1589
1590 return sd_bus_reply_method_return(message, "s", name);
1591}
1592
313fe66f 1593static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
4afd3348 1594 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
718db961
LP
1595 Manager *m = userdata;
1596 UnitFileList *item;
1597 Hashmap *h;
1598 Iterator i;
1599 int r;
1600
718db961
LP
1601 assert(message);
1602 assert(m);
1603
283868e1
SW
1604 /* Anyone can call this method */
1605
8a188de9 1606 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1607 if (r < 0)
1608 return r;
718db961 1609
df2d202e 1610 r = sd_bus_message_new_method_return(message, &reply);
718db961 1611 if (r < 0)
ebcf1f97 1612 return r;
c0576cd6 1613
d5099efc 1614 h = hashmap_new(&string_hash_ops);
718db961 1615 if (!h)
ebcf1f97 1616 return -ENOMEM;
c0576cd6 1617
313fe66f 1618 r = unit_file_get_list(m->unit_file_scope, NULL, h, states, patterns);
ebcf1f97 1619 if (r < 0)
718db961 1620 goto fail;
718db961
LP
1621
1622 r = sd_bus_message_open_container(reply, 'a', "(ss)");
ebcf1f97 1623 if (r < 0)
718db961 1624 goto fail;
718db961
LP
1625
1626 HASHMAP_FOREACH(item, h, i) {
1627
1628 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
ebcf1f97 1629 if (r < 0)
718db961 1630 goto fail;
718db961 1631 }
c0576cd6 1632
718db961 1633 unit_file_list_free(h);
c0576cd6 1634
718db961
LP
1635 r = sd_bus_message_close_container(reply);
1636 if (r < 0)
ebcf1f97 1637 return r;
8d0e38a2 1638
9030ca46 1639 return sd_bus_send(NULL, reply, NULL);
99504dd4 1640
718db961
LP
1641fail:
1642 unit_file_list_free(h);
1643 return r;
1644}
99504dd4 1645
313fe66f 1646static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1647 return list_unit_files_by_patterns(message, userdata, error, NULL, NULL);
1648}
1649
1650static int method_list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1651 _cleanup_strv_free_ char **states = NULL;
1652 _cleanup_strv_free_ char **patterns = NULL;
1653 int r;
1654
1655 r = sd_bus_message_read_strv(message, &states);
1656 if (r < 0)
1657 return r;
1658
1659 r = sd_bus_message_read_strv(message, &patterns);
1660 if (r < 0)
1661 return r;
1662
1663 return list_unit_files_by_patterns(message, userdata, error, states, patterns);
1664}
1665
19070062 1666static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1667 Manager *m = userdata;
1668 const char *name;
1669 UnitFileState state;
718db961 1670 int r;
99504dd4 1671
718db961
LP
1672 assert(message);
1673 assert(m);
8e2af478 1674
283868e1
SW
1675 /* Anyone can call this method */
1676
8a188de9 1677 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1678 if (r < 0)
1679 return r;
8e2af478 1680
718db961
LP
1681 r = sd_bus_message_read(message, "s", &name);
1682 if (r < 0)
ebcf1f97 1683 return r;
8e2af478 1684
463d0d15 1685 r = unit_file_get_state(m->unit_file_scope, NULL, name, &state);
0ec0deaa
LP
1686 if (r < 0)
1687 return r;
8e2af478 1688
df2d202e 1689 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
718db961 1690}
8e2af478 1691
19070062 1692static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
1693 _cleanup_free_ char *default_target = NULL;
1694 Manager *m = userdata;
718db961 1695 int r;
c2756a68 1696
718db961
LP
1697 assert(message);
1698 assert(m);
c2756a68 1699
283868e1
SW
1700 /* Anyone can call this method */
1701
8a188de9 1702 r = mac_selinux_access_check(message, "status", error);
ebcf1f97
LP
1703 if (r < 0)
1704 return r;
c2756a68 1705
463d0d15 1706 r = unit_file_get_default(m->unit_file_scope, NULL, &default_target);
718db961 1707 if (r < 0)
ebcf1f97 1708 return r;
c2756a68 1709
df2d202e 1710 return sd_bus_reply_method_return(message, "s", default_target);
718db961 1711}
c2756a68 1712
8f8f05a9 1713static int send_unit_files_changed(sd_bus *bus, void *userdata) {
4afd3348 1714 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
718db961
LP
1715 int r;
1716
1717 assert(bus);
1718
151b9b96 1719 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
718db961
LP
1720 if (r < 0)
1721 return r;
1722
8f8f05a9 1723 return sd_bus_send(bus, message, NULL);
718db961
LP
1724}
1725
1726static int reply_unit_file_changes_and_free(
1727 Manager *m,
718db961
LP
1728 sd_bus_message *message,
1729 int carries_install_info,
1730 UnitFileChange *changes,
1731 unsigned n_changes) {
1732
4afd3348 1733 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
718db961
LP
1734 unsigned i;
1735 int r;
1736
795ff6d5
ZJS
1737 if (unit_file_changes_have_modification(changes, n_changes)) {
1738 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1739 if (r < 0)
1740 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1741 }
718db961 1742
df2d202e 1743 r = sd_bus_message_new_method_return(message, &reply);
718db961
LP
1744 if (r < 0)
1745 goto fail;
1746
1747 if (carries_install_info >= 0) {
1748 r = sd_bus_message_append(reply, "b", carries_install_info);
c2756a68 1749 if (r < 0)
718db961
LP
1750 goto fail;
1751 }
1752
1753 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1754 if (r < 0)
1755 goto fail;
c2756a68 1756
af3d8113
ZJS
1757 for (i = 0; i < n_changes; i++)
1758 if (changes[i].type >= 0) {
1759 const char *change = unit_file_change_type_to_string(changes[i].type);
1760 assert(change != NULL);
1761
1762 r = sd_bus_message_append(
1763 reply, "(sss)",
1764 change,
1765 changes[i].path,
1766 changes[i].source);
1767 if (r < 0)
1768 goto fail;
1769 }
c2756a68 1770
718db961
LP
1771 r = sd_bus_message_close_container(reply);
1772 if (r < 0)
1773 goto fail;
c2756a68 1774
24f412ca 1775 unit_file_changes_free(changes, n_changes);
9030ca46 1776 return sd_bus_send(NULL, reply, NULL);
c2756a68 1777
718db961
LP
1778fail:
1779 unit_file_changes_free(changes, n_changes);
ebcf1f97 1780 return r;
718db961 1781}
cad45ba1 1782
af3d8113
ZJS
1783/* Create an error reply, using the error information from changes[]
1784 * if possible, and fall back to generating an error from error code c.
1785 * The error message only describes the first error.
1786 *
1787 * Coordinate with unit_file_dump_changes() in install.c.
1788 */
1789static int install_error(
1790 sd_bus_error *error,
1791 int c,
1792 UnitFileChange *changes,
1793 unsigned n_changes) {
1794 int r;
1795 unsigned i;
8e20adca
LP
1796 assert(c < 0);
1797
af3d8113
ZJS
1798 for (i = 0; i < n_changes; i++)
1799 switch(changes[i].type) {
1800 case 0 ... INT_MAX:
1801 continue;
1802 case -EEXIST:
1803 if (changes[i].source)
1804 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
1805 "File %s already exists and is a symlink to %s.",
1806 changes[i].path, changes[i].source);
1807 else
1808 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
1809 "File %s already exists.",
1810 changes[i].path);
1811 goto found;
1812 case -ERFKILL:
1813 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED,
1814 "Unit file %s is masked.", changes[i].path);
1815 goto found;
1816 case -EADDRNOTAVAIL:
1817 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED,
1818 "Unit %s is transient or generated.", changes[i].path);
1819 goto found;
1820 case -ELOOP:
1821 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED,
1822 "Refusing to operate on linked unit file %s", changes[i].path);
1823 goto found;
1824 default:
1825 r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path);
1826 goto found;
1827 }
8e20adca 1828
af3d8113
ZJS
1829 r = c;
1830 found:
1831 unit_file_changes_free(changes, n_changes);
1832 return r;
8e20adca
LP
1833}
1834
718db961 1835static int method_enable_unit_files_generic(
718db961 1836 sd_bus_message *message,
d309c1c3 1837 Manager *m,
718db961 1838 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
ebcf1f97
LP
1839 bool carries_install_info,
1840 sd_bus_error *error) {
718db961
LP
1841
1842 _cleanup_strv_free_ char **l = NULL;
1843 UnitFileChange *changes = NULL;
1844 unsigned n_changes = 0;
718db961
LP
1845 int runtime, force, r;
1846
718db961
LP
1847 assert(message);
1848 assert(m);
cad45ba1 1849
718db961
LP
1850 r = sd_bus_message_read_strv(message, &l);
1851 if (r < 0)
ebcf1f97 1852 return r;
90bb85e1 1853
d309c1c3
LP
1854 r = sd_bus_message_read(message, "bb", &runtime, &force);
1855 if (r < 0)
1856 return r;
1857
1d22e906
LP
1858 r = bus_verify_manage_unit_files_async(m, message, error);
1859 if (r < 0)
1860 return r;
1861 if (r == 0)
1862 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1863
463d0d15 1864 r = call(m->unit_file_scope, runtime, NULL, l, force, &changes, &n_changes);
af3d8113
ZJS
1865 if (r < 0)
1866 return install_error(error, r, changes, n_changes);
718db961 1867
19070062 1868 return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes);
718db961 1869}
c87eba54 1870
19070062 1871static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1872 return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error);
718db961 1873}
ea430986 1874
19070062 1875static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1876 return method_enable_unit_files_generic(message, userdata, unit_file_reenable, true, error);
718db961
LP
1877}
1878
19070062 1879static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1880 return method_enable_unit_files_generic(message, userdata, unit_file_link, false, error);
718db961
LP
1881}
1882
d309c1c3
LP
1883static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1884 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1885}
1886
19070062 1887static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1888 return method_enable_unit_files_generic(message, userdata, unit_file_preset_without_mode, true, error);
718db961
LP
1889}
1890
19070062 1891static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1892 return method_enable_unit_files_generic(message, userdata, unit_file_mask, false, error);
718db961 1893}
ea430986 1894
19070062 1895static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d309c1c3
LP
1896
1897 _cleanup_strv_free_ char **l = NULL;
d309c1c3
LP
1898 UnitFileChange *changes = NULL;
1899 unsigned n_changes = 0;
1900 Manager *m = userdata;
1901 UnitFilePresetMode mm;
d309c1c3
LP
1902 int runtime, force, r;
1903 const char *mode;
1904
d309c1c3
LP
1905 assert(message);
1906 assert(m);
1907
1908 r = sd_bus_message_read_strv(message, &l);
1909 if (r < 0)
1910 return r;
1911
1912 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1913 if (r < 0)
1914 return r;
1915
1916 if (isempty(mode))
1917 mm = UNIT_FILE_PRESET_FULL;
1918 else {
1919 mm = unit_file_preset_mode_from_string(mode);
1920 if (mm < 0)
1921 return -EINVAL;
1922 }
1923
1d22e906
LP
1924 r = bus_verify_manage_unit_files_async(m, message, error);
1925 if (r < 0)
1926 return r;
1927 if (r == 0)
1928 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1929
463d0d15 1930 r = unit_file_preset(m->unit_file_scope, runtime, NULL, l, mm, force, &changes, &n_changes);
af3d8113
ZJS
1931 if (r < 0)
1932 return install_error(error, r, changes, n_changes);
d309c1c3 1933
19070062 1934 return reply_unit_file_changes_and_free(m, message, r, changes, n_changes);
d309c1c3
LP
1935}
1936
718db961 1937static int method_disable_unit_files_generic(
718db961 1938 sd_bus_message *message,
596fc263 1939 Manager *m,
ebcf1f97
LP
1940 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1941 sd_bus_error *error) {
718db961
LP
1942
1943 _cleanup_strv_free_ char **l = NULL;
1944 UnitFileChange *changes = NULL;
1945 unsigned n_changes = 0;
718db961
LP
1946 int r, runtime;
1947
718db961
LP
1948 assert(message);
1949 assert(m);
1950
df823e23 1951 r = sd_bus_message_read_strv(message, &l);
ebcf1f97
LP
1952 if (r < 0)
1953 return r;
718db961 1954
df823e23 1955 r = sd_bus_message_read(message, "b", &runtime);
718db961 1956 if (r < 0)
ebcf1f97 1957 return r;
718db961 1958
1d22e906
LP
1959 r = bus_verify_manage_unit_files_async(m, message, error);
1960 if (r < 0)
1961 return r;
1962 if (r == 0)
1963 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1964
463d0d15 1965 r = call(m->unit_file_scope, runtime, NULL, l, &changes, &n_changes);
af3d8113
ZJS
1966 if (r < 0)
1967 return install_error(error, r, changes, n_changes);
718db961 1968
19070062 1969 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
718db961 1970}
ea430986 1971
19070062 1972static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1973 return method_disable_unit_files_generic(message, userdata, unit_file_disable, error);
ea430986
LP
1974}
1975
19070062 1976static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9a7c402b 1977 return method_disable_unit_files_generic(message, userdata, unit_file_unmask, error);
718db961
LP
1978}
1979
344ca755
LP
1980static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1981 _cleanup_strv_free_ char **l = NULL;
1982 UnitFileChange *changes = NULL;
1983 unsigned n_changes = 0;
1984 Manager *m = userdata;
1985 int r;
1986
1987 assert(message);
1988 assert(m);
1989
1990 r = sd_bus_message_read_strv(message, &l);
1991 if (r < 0)
1992 return r;
1993
1994 r = bus_verify_manage_unit_files_async(m, message, error);
1995 if (r < 0)
1996 return r;
1997 if (r == 0)
1998 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1999
2000 r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes);
af3d8113
ZJS
2001 if (r < 0)
2002 return install_error(error, r, changes, n_changes);
344ca755
LP
2003
2004 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
2005}
2006
19070062 2007static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961
LP
2008 UnitFileChange *changes = NULL;
2009 unsigned n_changes = 0;
2010 Manager *m = userdata;
718db961
LP
2011 const char *name;
2012 int force, r;
2013
718db961
LP
2014 assert(message);
2015 assert(m);
2016
1d22e906 2017 r = mac_selinux_access_check(message, "enable", error);
283868e1
SW
2018 if (r < 0)
2019 return r;
283868e1 2020
1d22e906 2021 r = sd_bus_message_read(message, "sb", &name, &force);
ebcf1f97
LP
2022 if (r < 0)
2023 return r;
718db961 2024
1d22e906 2025 r = bus_verify_manage_unit_files_async(m, message, error);
718db961 2026 if (r < 0)
ebcf1f97 2027 return r;
1d22e906
LP
2028 if (r == 0)
2029 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
718db961 2030
463d0d15 2031 r = unit_file_set_default(m->unit_file_scope, NULL, name, force, &changes, &n_changes);
af3d8113
ZJS
2032 if (r < 0)
2033 return install_error(error, r, changes, n_changes);
718db961 2034
19070062 2035 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
718db961
LP
2036}
2037
19070062 2038static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
d309c1c3
LP
2039 UnitFileChange *changes = NULL;
2040 unsigned n_changes = 0;
2041 Manager *m = userdata;
2042 UnitFilePresetMode mm;
d309c1c3
LP
2043 const char *mode;
2044 int force, runtime, r;
2045
d309c1c3
LP
2046 assert(message);
2047 assert(m);
2048
8a188de9 2049 r = mac_selinux_access_check(message, "enable", error);
d309c1c3
LP
2050 if (r < 0)
2051 return r;
2052
2053 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
2054 if (r < 0)
2055 return r;
2056
2057 if (isempty(mode))
2058 mm = UNIT_FILE_PRESET_FULL;
2059 else {
2060 mm = unit_file_preset_mode_from_string(mode);
2061 if (mm < 0)
2062 return -EINVAL;
2063 }
2064
1d22e906
LP
2065 r = bus_verify_manage_unit_files_async(m, message, error);
2066 if (r < 0)
2067 return r;
2068 if (r == 0)
2069 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2070
463d0d15 2071 r = unit_file_preset_all(m->unit_file_scope, runtime, NULL, mm, force, &changes, &n_changes);
af3d8113
ZJS
2072 if (r < 0)
2073 return install_error(error, r, changes, n_changes);
d309c1c3 2074
19070062 2075 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
d309c1c3
LP
2076}
2077
19070062 2078static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
e94937df
LN
2079 _cleanup_strv_free_ char **l = NULL;
2080 Manager *m = userdata;
2081 UnitFileChange *changes = NULL;
2082 unsigned n_changes = 0;
e94937df 2083 int runtime, force, r;
596fc263 2084 char *target, *type;
e94937df
LN
2085 UnitDependency dep;
2086
e94937df
LN
2087 assert(message);
2088 assert(m);
2089
2090 r = bus_verify_manage_unit_files_async(m, message, error);
2091 if (r < 0)
2092 return r;
2093 if (r == 0)
2094 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2095
2096 r = sd_bus_message_read_strv(message, &l);
2097 if (r < 0)
2098 return r;
2099
2100 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
2101 if (r < 0)
2102 return r;
2103
2104 dep = unit_dependency_from_string(type);
2105 if (dep < 0)
2106 return -EINVAL;
2107
463d0d15 2108 r = unit_file_add_dependency(m->unit_file_scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
af3d8113
ZJS
2109 if (r < 0)
2110 return install_error(error, r, changes, n_changes);
e94937df 2111
19070062 2112 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
e94937df
LN
2113}
2114
718db961
LP
2115const sd_bus_vtable bus_manager_vtable[] = {
2116 SD_BUS_VTABLE_START(0),
2117
556089dc
LP
2118 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2119 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2120 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
7452394e 2121 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
2122 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2123 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2124 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2125 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2126 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2127 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2128 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2129 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2130 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2131 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2132 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2133 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2134 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
2135 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
2136 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
2137 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
03455c28 2138 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
718db961
LP
2139 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
2140 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
2141 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
2142 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
2143 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
556089dc
LP
2144 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
2145 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
a3c4eb07 2146 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
2147 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
2148 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
4c3f1641
LP
2149 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
2150 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
b272b74d 2151 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
f755e3b7 2152 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
287419c1 2153 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
670a3efe
EV
2154 SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2155 SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2156 SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2157 SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
f0367da7
LP
2158 SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
2159 SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */
670a3efe
EV
2160 SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
2161 SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2162 SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2163 SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2164 SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2165 SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2166 SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2167 SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2168 SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2169 SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2170 SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2171 SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2172 SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2173 SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2174 SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2175 SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2176 SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2177 SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2178 SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2179 SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2180 SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2181 SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2182 SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2183 SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2184 SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2185 SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2186 SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2187 SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2188 SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2189 SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2190 SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2191 SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2192 SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2193 SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2194 SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
97eb4231 2195 SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 2196 SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
0af20ea2 2197 SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
eed67a30 2198 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
718db961 2199
adacb957
LP
2200 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2201 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2202 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
283868e1
SW
2203 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2204 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
2205 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2206 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2207 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2208 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2209 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2210 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2211 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2212 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2213 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
2214 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
291d565a 2215 SD_BUS_METHOD("GetUnitProcesses", "s", "a(sus)", method_get_unit_processes, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957 2216 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
283868e1 2217 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
1d22e906
LP
2218 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2219 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957 2220 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
cdc06ed7 2221 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
313fe66f 2222 SD_BUS_METHOD("ListUnitsByPatterns", "asas", "a(ssssssouso)", method_list_units_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
6900c740 2223 SD_BUS_METHOD("ListUnitsByNames", "as", "a(ssssssouso)", method_list_units_by_names, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957
LP
2224 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2225 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2226 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2227 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
36b4a7ba
ZJS
2228 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2229 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
283868e1
SW
2230 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
2231 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
718db961 2232 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
adacb957
LP
2233 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2234 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2235 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2236 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2237 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1d22e906
LP
2238 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2239 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2240 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957 2241 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
313fe66f 2242 SD_BUS_METHOD("ListUnitFilesByPatterns", "asas", "a(ss)", method_list_unit_files_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957 2243 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
283868e1
SW
2244 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2245 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2246 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2247 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2248 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2249 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2250 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2251 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
344ca755 2252 SD_BUS_METHOD("RevertUnitFiles", "as", "a(sss)", method_revert_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
283868e1 2253 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
adacb957 2254 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
283868e1 2255 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
e94937df 2256 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
287419c1 2257 SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
29206d46
LP
2258 SD_BUS_METHOD("LookupDynamicUserByName", "s", "u", method_lookup_dynamic_user_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
2259 SD_BUS_METHOD("LookupDynamicUserByUID", "u", "s", method_lookup_dynamic_user_by_uid, SD_BUS_VTABLE_UNPRIVILEGED),
718db961
LP
2260
2261 SD_BUS_SIGNAL("UnitNew", "so", 0),
2262 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2263 SD_BUS_SIGNAL("JobNew", "uos", 0),
2264 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2265 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2266 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2267 SD_BUS_SIGNAL("Reloading", "b", 0),
2268
2269 SD_BUS_VTABLE_END
ea430986 2270};
718db961 2271
8f8f05a9 2272static int send_finished(sd_bus *bus, void *userdata) {
4afd3348 2273 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
718db961
LP
2274 usec_t *times = userdata;
2275 int r;
2276
2277 assert(bus);
2278 assert(times);
2279
151b9b96 2280 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
718db961
LP
2281 if (r < 0)
2282 return r;
2283
2284 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2285 if (r < 0)
2286 return r;
2287
8f8f05a9 2288 return sd_bus_send(bus, message, NULL);
718db961
LP
2289}
2290
39abcaee 2291void bus_manager_send_finished(
718db961
LP
2292 Manager *m,
2293 usec_t firmware_usec,
2294 usec_t loader_usec,
2295 usec_t kernel_usec,
2296 usec_t initrd_usec,
2297 usec_t userspace_usec,
2298 usec_t total_usec) {
2299
39abcaee
LP
2300 int r;
2301
718db961
LP
2302 assert(m);
2303
8f8f05a9
LP
2304 r = bus_foreach_bus(
2305 m,
2306 NULL,
2307 send_finished,
2308 (usec_t[6]) {
2309 firmware_usec,
2310 loader_usec,
2311 kernel_usec,
2312 initrd_usec,
2313 userspace_usec,
2314 total_usec
2315 });
39abcaee 2316 if (r < 0)
da927ba9 2317 log_debug_errno(r, "Failed to send finished signal: %m");
718db961
LP
2318}
2319
8f8f05a9 2320static int send_reloading(sd_bus *bus, void *userdata) {
4afd3348 2321 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
718db961
LP
2322 int r;
2323
2324 assert(bus);
2325
151b9b96 2326 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
718db961
LP
2327 if (r < 0)
2328 return r;
2329
2330 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2331 if (r < 0)
2332 return r;
2333
8f8f05a9 2334 return sd_bus_send(bus, message, NULL);
718db961
LP
2335}
2336
39abcaee
LP
2337void bus_manager_send_reloading(Manager *m, bool active) {
2338 int r;
2339
718db961
LP
2340 assert(m);
2341
8f8f05a9 2342 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
39abcaee 2343 if (r < 0)
da927ba9 2344 log_debug_errno(r, "Failed to send reloading signal: %m");
03455c28
LDM
2345}
2346
2347static int send_changed_signal(sd_bus *bus, void *userdata) {
2348 assert(bus);
2349
2350 return sd_bus_emit_properties_changed_strv(bus,
2351 "/org/freedesktop/systemd1",
2352 "org.freedesktop.systemd1.Manager",
2353 NULL);
2354}
39abcaee 2355
03455c28
LDM
2356void bus_manager_send_change_signal(Manager *m) {
2357 int r;
2358
2359 assert(m);
2360
2361 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2362 if (r < 0)
2363 log_debug_errno(r, "Failed to send manager change signal: %m");
718db961 2364}