]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / dbus-execute.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
4139c1b2
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
4139c1b2
LP
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
5430f7f2 15 Lesser General Public License for more details.
4139c1b2 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
4139c1b2
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
82c121a4 21#include <sys/prctl.h>
4139c1b2 22
349cc4a5 23#if HAVE_SECCOMP
57183d11
LP
24#include <seccomp.h>
25#endif
26
3ffd4af2 27#include "af-list.h"
b5efdb8a 28#include "alloc-util.h"
718db961 29#include "bus-util.h"
cffaed83 30#include "cap-list.h"
d3070fbd 31#include "capability-util.h"
3ffd4af2 32#include "dbus-execute.h"
c7040b5d 33#include "env-util.h"
cffaed83 34#include "errno-list.h"
3ffd4af2
LP
35#include "execute.h"
36#include "fd-util.h"
37#include "fileio.h"
d3070fbd 38#include "io-util.h"
3ffd4af2 39#include "ioprio.h"
d3070fbd 40#include "journal-util.h"
3ffd4af2 41#include "missing.h"
83555251 42#include "mount-util.h"
417116f2 43#include "namespace.h"
6bedfcbb 44#include "parse-util.h"
9b15b784 45#include "path-util.h"
7b3e062c 46#include "process-util.h"
78f22b97 47#include "rlimit-util.h"
349cc4a5 48#if HAVE_SECCOMP
57183d11
LP
49#include "seccomp-util.h"
50#endif
cffaed83 51#include "securebits-util.h"
6bedfcbb 52#include "strv.h"
7ccbd1ae 53#include "syslog-util.h"
f900f582 54#include "unit-printf.h"
6f3e7985 55#include "user-util.h"
6bedfcbb 56#include "utf8.h"
57183d11 57
718db961 58BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
718db961 59static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
8c7be95e 60
023a4f67 61static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
53f47dfc 62static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
b1edf445 63static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
53f47dfc 64
1b8689f9
LP
65static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
66static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
417116f2 67
718db961
LP
68static int property_get_environment_files(
69 sd_bus *bus,
70 const char *path,
71 const char *interface,
72 const char *property,
73 sd_bus_message *reply,
ebcf1f97
LP
74 void *userdata,
75 sd_bus_error *error) {
8c7be95e 76
718db961
LP
77 ExecContext *c = userdata;
78 char **j;
79 int r;
8c7be95e 80
718db961
LP
81 assert(bus);
82 assert(reply);
83 assert(c);
84
85 r = sd_bus_message_open_container(reply, 'a', "(sb)");
86 if (r < 0)
87 return r;
8c7be95e 88
718db961
LP
89 STRV_FOREACH(j, c->environment_files) {
90 const char *fn = *j;
8c7be95e 91
718db961
LP
92 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
93 if (r < 0)
94 return r;
8c7be95e
LP
95 }
96
718db961
LP
97 return sd_bus_message_close_container(reply);
98}
99
718db961
LP
100static int property_get_oom_score_adjust(
101 sd_bus *bus,
102 const char *path,
103 const char *interface,
104 const char *property,
105 sd_bus_message *reply,
ebcf1f97
LP
106 void *userdata,
107 sd_bus_error *error) {
718db961
LP
108
109
110 ExecContext *c = userdata;
82c121a4
LP
111 int32_t n;
112
718db961
LP
113 assert(bus);
114 assert(reply);
82c121a4
LP
115 assert(c);
116
dd6c17b1
LP
117 if (c->oom_score_adjust_set)
118 n = c->oom_score_adjust;
82c121a4 119 else {
68eda4bd 120 _cleanup_free_ char *t = NULL;
82c121a4
LP
121
122 n = 0;
718db961 123 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
e4e73a63 124 safe_atoi32(t, &n);
82c121a4
LP
125 }
126
718db961 127 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
128}
129
718db961
LP
130static int property_get_nice(
131 sd_bus *bus,
132 const char *path,
133 const char *interface,
134 const char *property,
135 sd_bus_message *reply,
ebcf1f97
LP
136 void *userdata,
137 sd_bus_error *error) {
718db961
LP
138
139
140 ExecContext *c = userdata;
82c121a4
LP
141 int32_t n;
142
718db961
LP
143 assert(bus);
144 assert(reply);
82c121a4
LP
145 assert(c);
146
147 if (c->nice_set)
148 n = c->nice;
718db961
LP
149 else {
150 errno = 0;
82c121a4 151 n = getpriority(PRIO_PROCESS, 0);
b3267152 152 if (errno > 0)
718db961
LP
153 n = 0;
154 }
82c121a4 155
718db961 156 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
157}
158
718db961
LP
159static int property_get_ioprio(
160 sd_bus *bus,
161 const char *path,
162 const char *interface,
163 const char *property,
164 sd_bus_message *reply,
ebcf1f97
LP
165 void *userdata,
166 sd_bus_error *error) {
718db961
LP
167
168
169 ExecContext *c = userdata;
82c121a4 170
718db961
LP
171 assert(bus);
172 assert(reply);
82c121a4
LP
173 assert(c);
174
7f452159
LP
175 return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
176}
82c121a4 177
7f452159
LP
178static int property_get_ioprio_class(
179 sd_bus *bus,
180 const char *path,
181 const char *interface,
182 const char *property,
183 sd_bus_message *reply,
184 void *userdata,
185 sd_bus_error *error) {
186
187
188 ExecContext *c = userdata;
189
190 assert(bus);
191 assert(reply);
192 assert(c);
193
194 return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
195}
196
7f452159
LP
197static int property_get_ioprio_priority(
198 sd_bus *bus,
199 const char *path,
200 const char *interface,
201 const char *property,
202 sd_bus_message *reply,
203 void *userdata,
204 sd_bus_error *error) {
205
206
207 ExecContext *c = userdata;
208
209 assert(bus);
210 assert(reply);
211 assert(c);
212
213 return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
82c121a4
LP
214}
215
718db961
LP
216static int property_get_cpu_sched_policy(
217 sd_bus *bus,
218 const char *path,
219 const char *interface,
220 const char *property,
221 sd_bus_message *reply,
ebcf1f97
LP
222 void *userdata,
223 sd_bus_error *error) {
718db961
LP
224
225 ExecContext *c = userdata;
82c121a4
LP
226 int32_t n;
227
718db961
LP
228 assert(bus);
229 assert(reply);
82c121a4
LP
230 assert(c);
231
232 if (c->cpu_sched_set)
233 n = c->cpu_sched_policy;
718db961 234 else {
82c121a4 235 n = sched_getscheduler(0);
718db961
LP
236 if (n < 0)
237 n = SCHED_OTHER;
238 }
82c121a4 239
718db961 240 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
241}
242
718db961
LP
243static int property_get_cpu_sched_priority(
244 sd_bus *bus,
245 const char *path,
246 const char *interface,
247 const char *property,
248 sd_bus_message *reply,
ebcf1f97
LP
249 void *userdata,
250 sd_bus_error *error) {
718db961
LP
251
252 ExecContext *c = userdata;
82c121a4
LP
253 int32_t n;
254
718db961
LP
255 assert(bus);
256 assert(reply);
82c121a4
LP
257 assert(c);
258
259 if (c->cpu_sched_set)
260 n = c->cpu_sched_priority;
261 else {
b92bea5d 262 struct sched_param p = {};
82c121a4 263
82c121a4
LP
264 if (sched_getparam(0, &p) >= 0)
265 n = p.sched_priority;
e62d8c39
ZJS
266 else
267 n = 0;
82c121a4
LP
268 }
269
718db961 270 return sd_bus_message_append(reply, "i", n);
82c121a4
LP
271}
272
718db961
LP
273static int property_get_cpu_affinity(
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) {
82c121a4 281
718db961 282 ExecContext *c = userdata;
82c121a4 283
718db961
LP
284 assert(bus);
285 assert(reply);
286 assert(c);
82c121a4
LP
287
288 if (c->cpuset)
718db961 289 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
82c121a4 290 else
718db961 291 return sd_bus_message_append_array(reply, 'y', NULL, 0);
82c121a4
LP
292}
293
718db961
LP
294static int property_get_timer_slack_nsec(
295 sd_bus *bus,
296 const char *path,
297 const char *interface,
298 const char *property,
299 sd_bus_message *reply,
ebcf1f97
LP
300 void *userdata,
301 sd_bus_error *error) {
718db961
LP
302
303 ExecContext *c = userdata;
82c121a4
LP
304 uint64_t u;
305
718db961
LP
306 assert(bus);
307 assert(reply);
82c121a4
LP
308 assert(c);
309
3a43da28 310 if (c->timer_slack_nsec != NSEC_INFINITY)
03fae018 311 u = (uint64_t) c->timer_slack_nsec;
82c121a4
LP
312 else
313 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
314
718db961 315 return sd_bus_message_append(reply, "t", u);
82c121a4
LP
316}
317
718db961
LP
318static int property_get_capability_bounding_set(
319 sd_bus *bus,
320 const char *path,
321 const char *interface,
322 const char *property,
323 sd_bus_message *reply,
ebcf1f97
LP
324 void *userdata,
325 sd_bus_error *error) {
260abb78 326
718db961
LP
327 ExecContext *c = userdata;
328
329 assert(bus);
330 assert(reply);
260abb78
LP
331 assert(c);
332
a103496c 333 return sd_bus_message_append(reply, "t", c->capability_bounding_set);
260abb78
LP
334}
335
755d4b67
IP
336static int property_get_ambient_capabilities(
337 sd_bus *bus,
338 const char *path,
339 const char *interface,
340 const char *property,
341 sd_bus_message *reply,
342 void *userdata,
343 sd_bus_error *error) {
344
345 ExecContext *c = userdata;
346
347 assert(bus);
348 assert(reply);
349 assert(c);
350
351 return sd_bus_message_append(reply, "t", c->capability_ambient_set);
352}
353
479050b3 354static int property_get_empty_string(
718db961
LP
355 sd_bus *bus,
356 const char *path,
357 const char *interface,
358 const char *property,
359 sd_bus_message *reply,
ebcf1f97
LP
360 void *userdata,
361 sd_bus_error *error) {
718db961 362
718db961
LP
363 assert(bus);
364 assert(reply);
82c121a4 365
479050b3 366 return sd_bus_message_append(reply, "s", "");
82c121a4
LP
367}
368
718db961
LP
369static int property_get_syscall_filter(
370 sd_bus *bus,
371 const char *path,
372 const char *interface,
373 const char *property,
374 sd_bus_message *reply,
ebcf1f97
LP
375 void *userdata,
376 sd_bus_error *error) {
82c121a4 377
17df7223
LP
378 ExecContext *c = userdata;
379 _cleanup_strv_free_ char **l = NULL;
57183d11
LP
380 int r;
381
349cc4a5 382#if HAVE_SECCOMP
17df7223 383 Iterator i;
8cfa775f 384 void *id, *val;
351a19b1 385#endif
17df7223
LP
386
387 assert(bus);
388 assert(reply);
389 assert(c);
390
57183d11
LP
391 r = sd_bus_message_open_container(reply, 'r', "bas");
392 if (r < 0)
393 return r;
394
395 r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
396 if (r < 0)
397 return r;
398
349cc4a5 399#if HAVE_SECCOMP
8cfa775f
YW
400 HASHMAP_FOREACH_KEY(val, id, c->syscall_filter, i) {
401 _cleanup_free_ char *name = NULL;
402 const char *e = NULL;
403 char *s;
404 int num = PTR_TO_INT(val);
17df7223
LP
405
406 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
407 if (!name)
408 continue;
409
8cfa775f
YW
410 if (num >= 0) {
411 e = errno_to_name(num);
412 if (e) {
413 s = strjoin(name, ":", e);
414 if (!s)
415 return -ENOMEM;
416 } else {
417 r = asprintf(&s, "%s:%d", name, num);
418 if (r < 0)
419 return -ENOMEM;
420 }
421 } else {
422 s = name;
423 name = NULL;
424 }
425
426 r = strv_consume(&l, s);
6e18964d
ZJS
427 if (r < 0)
428 return r;
17df7223 429 }
351a19b1 430#endif
17df7223
LP
431
432 strv_sort(l);
433
57183d11
LP
434 r = sd_bus_message_append_strv(reply, l);
435 if (r < 0)
436 return r;
17df7223 437
57183d11
LP
438 return sd_bus_message_close_container(reply);
439}
17df7223 440
57183d11
LP
441static int property_get_syscall_archs(
442 sd_bus *bus,
443 const char *path,
444 const char *interface,
445 const char *property,
446 sd_bus_message *reply,
447 void *userdata,
448 sd_bus_error *error) {
449
450 ExecContext *c = userdata;
451 _cleanup_strv_free_ char **l = NULL;
452 int r;
453
349cc4a5 454#if HAVE_SECCOMP
57183d11
LP
455 Iterator i;
456 void *id;
457#endif
458
459 assert(bus);
460 assert(reply);
461 assert(c);
17df7223 462
349cc4a5 463#if HAVE_SECCOMP
57183d11
LP
464 SET_FOREACH(id, c->syscall_archs, i) {
465 const char *name;
466
467 name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
468 if (!name)
469 continue;
470
471 r = strv_extend(&l, name);
472 if (r < 0)
473 return -ENOMEM;
17df7223 474 }
57183d11
LP
475#endif
476
477 strv_sort(l);
478
479 r = sd_bus_message_append_strv(reply, l);
480 if (r < 0)
481 return r;
17df7223 482
57183d11 483 return 0;
17df7223
LP
484}
485
486static int property_get_syscall_errno(
487 sd_bus *bus,
488 const char *path,
489 const char *interface,
490 const char *property,
491 sd_bus_message *reply,
492 void *userdata,
493 sd_bus_error *error) {
494
718db961 495 ExecContext *c = userdata;
82c121a4 496
718db961
LP
497 assert(bus);
498 assert(reply);
499 assert(c);
82c121a4 500
17df7223 501 return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
718db961 502}
82c121a4 503
5f8640fb
LP
504static int property_get_selinux_context(
505 sd_bus *bus,
506 const char *path,
507 const char *interface,
508 const char *property,
509 sd_bus_message *reply,
510 void *userdata,
511 sd_bus_error *error) {
512
513 ExecContext *c = userdata;
514
515 assert(bus);
516 assert(reply);
517 assert(c);
518
519 return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
520}
521
eef65bf3
MS
522static int property_get_apparmor_profile(
523 sd_bus *bus,
524 const char *path,
525 const char *interface,
526 const char *property,
527 sd_bus_message *reply,
528 void *userdata,
529 sd_bus_error *error) {
530
531 ExecContext *c = userdata;
532
533 assert(bus);
534 assert(reply);
535 assert(c);
536
537 return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
538}
539
2ca620c4
WC
540static int property_get_smack_process_label(
541 sd_bus *bus,
542 const char *path,
543 const char *interface,
544 const char *property,
545 sd_bus_message *reply,
546 void *userdata,
547 sd_bus_error *error) {
548
549 ExecContext *c = userdata;
550
551 assert(bus);
552 assert(reply);
553 assert(c);
554
555 return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
556}
557
ac45f971
LP
558static int property_get_personality(
559 sd_bus *bus,
560 const char *path,
561 const char *interface,
562 const char *property,
563 sd_bus_message *reply,
564 void *userdata,
565 sd_bus_error *error) {
566
567 ExecContext *c = userdata;
568
569 assert(bus);
570 assert(reply);
571 assert(c);
572
573 return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
574}
575
4298d0b5
LP
576static int property_get_address_families(
577 sd_bus *bus,
578 const char *path,
579 const char *interface,
580 const char *property,
581 sd_bus_message *reply,
582 void *userdata,
583 sd_bus_error *error) {
584
585 ExecContext *c = userdata;
586 _cleanup_strv_free_ char **l = NULL;
587 Iterator i;
588 void *af;
589 int r;
590
591 assert(bus);
592 assert(reply);
593 assert(c);
594
595 r = sd_bus_message_open_container(reply, 'r', "bas");
596 if (r < 0)
597 return r;
598
599 r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
600 if (r < 0)
601 return r;
602
603 SET_FOREACH(af, c->address_families, i) {
604 const char *name;
605
606 name = af_to_name(PTR_TO_INT(af));
607 if (!name)
608 continue;
609
610 r = strv_extend(&l, name);
611 if (r < 0)
612 return -ENOMEM;
613 }
614
615 strv_sort(l);
616
617 r = sd_bus_message_append_strv(reply, l);
618 if (r < 0)
619 return r;
620
621 return sd_bus_message_close_container(reply);
622}
623
5f5d8eab
LP
624static int property_get_working_directory(
625 sd_bus *bus,
626 const char *path,
627 const char *interface,
628 const char *property,
629 sd_bus_message *reply,
630 void *userdata,
631 sd_bus_error *error) {
632
633 ExecContext *c = userdata;
634 const char *wd;
635
636 assert(bus);
637 assert(reply);
638 assert(c);
639
640 if (c->working_directory_home)
641 wd = "~";
642 else
643 wd = c->working_directory;
644
645 if (c->working_directory_missing_ok)
646 wd = strjoina("!", wd);
647
648 return sd_bus_message_append(reply, "s", wd);
649}
650
06f2ccf9
EV
651static int property_get_syslog_level(
652 sd_bus *bus,
653 const char *path,
654 const char *interface,
655 const char *property,
656 sd_bus_message *reply,
657 void *userdata,
658 sd_bus_error *error) {
659
660 ExecContext *c = userdata;
661
662 assert(bus);
663 assert(reply);
664 assert(c);
665
666 return sd_bus_message_append(reply, "i", LOG_PRI(c->syslog_priority));
667}
668
669static int property_get_syslog_facility(
670 sd_bus *bus,
671 const char *path,
672 const char *interface,
673 const char *property,
674 sd_bus_message *reply,
675 void *userdata,
676 sd_bus_error *error) {
677
678 ExecContext *c = userdata;
679
680 assert(bus);
681 assert(reply);
682 assert(c);
683
684 return sd_bus_message_append(reply, "i", LOG_FAC(c->syslog_priority));
685}
686
52c239d7
LB
687static int property_get_input_fdname(
688 sd_bus *bus,
689 const char *path,
690 const char *interface,
691 const char *property,
692 sd_bus_message *reply,
693 void *userdata,
694 sd_bus_error *error) {
695
696 ExecContext *c = userdata;
697 const char *name;
698
699 assert(bus);
700 assert(c);
701 assert(property);
702 assert(reply);
703
704 name = exec_context_fdname(c, STDIN_FILENO);
705
706 return sd_bus_message_append(reply, "s", name);
707}
708
709static int property_get_output_fdname(
710 sd_bus *bus,
711 const char *path,
712 const char *interface,
713 const char *property,
714 sd_bus_message *reply,
715 void *userdata,
716 sd_bus_error *error) {
717
718 ExecContext *c = userdata;
719 const char *name = NULL;
720
721 assert(bus);
722 assert(c);
723 assert(property);
724 assert(reply);
725
726 if (c->std_output == EXEC_OUTPUT_NAMED_FD && streq(property, "StandardOutputFileDescriptorName"))
727 name = exec_context_fdname(c, STDOUT_FILENO);
728 else if (c->std_error == EXEC_OUTPUT_NAMED_FD && streq(property, "StandardErrorFileDescriptorName"))
729 name = exec_context_fdname(c, STDERR_FILENO);
730
731 return sd_bus_message_append(reply, "s", name);
732}
733
d2d6c096
LP
734static int property_get_bind_paths(
735 sd_bus *bus,
736 const char *path,
737 const char *interface,
738 const char *property,
739 sd_bus_message *reply,
740 void *userdata,
741 sd_bus_error *error) {
742
743 ExecContext *c = userdata;
744 unsigned i;
745 bool ro;
746 int r;
747
748 assert(bus);
749 assert(c);
750 assert(property);
751 assert(reply);
752
753 ro = !!strstr(property, "ReadOnly");
754
755 r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
756 if (r < 0)
757 return r;
758
759 for (i = 0; i < c->n_bind_mounts; i++) {
760
761 if (ro != c->bind_mounts[i].read_only)
762 continue;
763
764 r = sd_bus_message_append(
765 reply, "(ssbt)",
766 c->bind_mounts[i].source,
767 c->bind_mounts[i].destination,
768 c->bind_mounts[i].ignore_enoent,
c9b06108 769 c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0);
d2d6c096
LP
770 if (r < 0)
771 return r;
772 }
773
774 return sd_bus_message_close_container(reply);
775}
776
d3070fbd
LP
777static int property_get_log_extra_fields(
778 sd_bus *bus,
779 const char *path,
780 const char *interface,
781 const char *property,
782 sd_bus_message *reply,
783 void *userdata,
784 sd_bus_error *error) {
785
786 ExecContext *c = userdata;
787 size_t i;
788 int r;
789
790 assert(bus);
791 assert(c);
792 assert(property);
793 assert(reply);
794
795 r = sd_bus_message_open_container(reply, 'a', "ay");
796 if (r < 0)
797 return r;
798
799 for (i = 0; i < c->n_log_extra_fields; i++) {
800 r = sd_bus_message_append_array(reply, 'y', c->log_extra_fields[i].iov_base, c->log_extra_fields[i].iov_len);
801 if (r < 0)
802 return r;
803 }
804
805 return sd_bus_message_close_container(reply);
806}
807
718db961
LP
808const sd_bus_vtable bus_exec_vtable[] = {
809 SD_BUS_VTABLE_START(0),
556089dc
LP
810 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
811 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
b4c14404 812 SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST),
00819cc1 813 SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL, offsetof(ExecContext, unset_environment), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 814 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 815 SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 816 SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 817 SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 818 SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 819 SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 820 SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 821 SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 822 SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 823 SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 824 SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 825 SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 826 SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 827 SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 828 SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 829 SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 830 SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 831 SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 832 SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 833 SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 834 SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 835 SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 836 SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 837 SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 838 SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 839 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 840 SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 841 SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 842 SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 843 SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 844 SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
c9d031c3 845 SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
147f6858 846 SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
5f5d8eab 847 SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 848 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
915e6d16 849 SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
850 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
851 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
7f452159
LP
852 SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
853 SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
854 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
855 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
856 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
857 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
858 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
859 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
860 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
52c239d7 861 SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_input_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 862 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
52c239d7 863 SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_output_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 864 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
52c239d7 865 SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_output_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
866 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
867 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
868 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
869 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
870 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
871 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
872 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
06f2ccf9
EV
873 SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
874 SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
d3070fbd
LP
875 SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
876 SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
877 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
878 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
755d4b67 879 SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
880 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
881 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
29206d46 882 SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
00d9ef85 883 SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 884 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc 885 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
2a624c36
AP
886 SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
887 SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
888 SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
889 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
890 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
7f112f50 891 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
59eeb84b 892 SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST),
502d704e 893 SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST),
59eeb84b 894 SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
d251207d
LP
895 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
896 SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
1b8689f9
LP
897 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
898 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
899 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
900 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
023a4f67 901 SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
5f8640fb 902 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
eef65bf3 903 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2ca620c4 904 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
905 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
906 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
57183d11
LP
907 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
908 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
17df7223 909 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
ac45f971 910 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
78e864e5 911 SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
4298d0b5 912 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
53f47dfc 913 SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
3536f49e
YW
914 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
915 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].paths), SD_BUS_VTABLE_PROPERTY_CONST),
e940c1ef
YW
916 SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
917 SD_BUS_PROPERTY("StateDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
3536f49e
YW
918 SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
919 SD_BUS_PROPERTY("CacheDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
920 SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
921 SD_BUS_PROPERTY("LogsDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].paths), SD_BUS_VTABLE_PROPERTY_CONST),
922 SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
923 SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST),
f3e43635 924 SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
f4170c67 925 SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
6a8c2d59 926 SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
d2d6c096
LP
927 SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
928 SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
5d997827 929 SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
b1edf445 930 SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
7f452159
LP
931
932 /* Obsolete/redundant properties: */
933 SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
934 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
935 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
936 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
937 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
938
718db961
LP
939 SD_BUS_VTABLE_END
940};
82c121a4 941
4d4c80d0
LP
942static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
943 int r;
944
945 assert(reply);
946 assert(c);
947
948 if (!c->path)
949 return 0;
950
951 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
952 if (r < 0)
953 return r;
954
955 r = sd_bus_message_append(reply, "s", c->path);
956 if (r < 0)
957 return r;
958
959 r = sd_bus_message_append_strv(reply, c->argv);
960 if (r < 0)
961 return r;
962
963 r = sd_bus_message_append(reply, "bttttuii",
3ed0cd26 964 !!(c->flags & EXEC_COMMAND_IGNORE_FAILURE),
4d4c80d0
LP
965 c->exec_status.start_timestamp.realtime,
966 c->exec_status.start_timestamp.monotonic,
967 c->exec_status.exit_timestamp.realtime,
968 c->exec_status.exit_timestamp.monotonic,
969 (uint32_t) c->exec_status.pid,
970 (int32_t) c->exec_status.code,
971 (int32_t) c->exec_status.status);
972 if (r < 0)
973 return r;
974
975 return sd_bus_message_close_container(reply);
976}
977
718db961
LP
978int bus_property_get_exec_command(
979 sd_bus *bus,
980 const char *path,
981 const char *interface,
982 const char *property,
983 sd_bus_message *reply,
ebcf1f97
LP
984 void *userdata,
985 sd_bus_error *ret_error) {
fe68089d 986
4d4c80d0 987 ExecCommand *c = (ExecCommand*) userdata;
718db961 988 int r;
fe68089d 989
718db961
LP
990 assert(bus);
991 assert(reply);
fe68089d 992
718db961
LP
993 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
994 if (r < 0)
995 return r;
fe68089d 996
4d4c80d0
LP
997 r = append_exec_command(reply, c);
998 if (r < 0)
999 return r;
fe68089d 1000
4d4c80d0
LP
1001 return sd_bus_message_close_container(reply);
1002}
718db961 1003
4d4c80d0
LP
1004int bus_property_get_exec_command_list(
1005 sd_bus *bus,
1006 const char *path,
1007 const char *interface,
1008 const char *property,
1009 sd_bus_message *reply,
1010 void *userdata,
1011 sd_bus_error *ret_error) {
718db961 1012
4d4c80d0
LP
1013 ExecCommand *c = *(ExecCommand**) userdata;
1014 int r;
718db961 1015
4d4c80d0
LP
1016 assert(bus);
1017 assert(reply);
1018
1019 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
1020 if (r < 0)
1021 return r;
718db961 1022
4d4c80d0
LP
1023 LIST_FOREACH(command, c, c) {
1024 r = append_exec_command(reply, c);
718db961
LP
1025 if (r < 0)
1026 return r;
fe68089d
LP
1027 }
1028
718db961 1029 return sd_bus_message_close_container(reply);
8351ceae 1030}
c7040b5d
LP
1031
1032int bus_exec_context_set_transient_property(
1033 Unit *u,
1034 ExecContext *c,
1035 const char *name,
1036 sd_bus_message *message,
1037 UnitSetPropertiesMode mode,
1038 sd_bus_error *error) {
1039
cab2aca3
LP
1040 const char *soft = NULL;
1041 int r, ri;
c7040b5d
LP
1042
1043 assert(u);
1044 assert(c);
1045 assert(name);
1046 assert(message);
1047
1048 if (streq(name, "User")) {
1049 const char *uu;
1050
1051 r = sd_bus_message_read(message, "s", &uu);
1052 if (r < 0)
1053 return r;
1054
6f3e7985
LP
1055 if (!isempty(uu) && !valid_user_group_name_or_id(uu))
1056 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu);
1057
c7040b5d 1058 if (mode != UNIT_CHECK) {
76736280
LP
1059
1060 if (isempty(uu))
1061 c->user = mfree(c->user);
1062 else if (free_and_strdup(&c->user, uu) < 0)
1063 return -ENOMEM;
c7040b5d 1064
b27b4b51 1065 unit_write_drop_in_private_format(u, mode, name, "User=%s", uu);
c7040b5d
LP
1066 }
1067
1068 return 1;
1069
1070 } else if (streq(name, "Group")) {
1071 const char *gg;
1072
1073 r = sd_bus_message_read(message, "s", &gg);
1074 if (r < 0)
1075 return r;
1076
6f3e7985
LP
1077 if (!isempty(gg) && !valid_user_group_name_or_id(gg))
1078 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg);
1079
c7040b5d 1080 if (mode != UNIT_CHECK) {
76736280
LP
1081
1082 if (isempty(gg))
1083 c->group = mfree(c->group);
1084 else if (free_and_strdup(&c->group, gg) < 0)
1085 return -ENOMEM;
c7040b5d 1086
b27b4b51 1087 unit_write_drop_in_private_format(u, mode, name, "Group=%s", gg);
c7040b5d
LP
1088 }
1089
1090 return 1;
cffaed83
YW
1091
1092 } else if (streq(name, "SupplementaryGroups")) {
1093 _cleanup_strv_free_ char **l = NULL;
1094 char **p;
1095
1096 r = sd_bus_message_read_strv(message, &l);
1097 if (r < 0)
1098 return r;
1099
1100 STRV_FOREACH(p, l) {
1101 if (!isempty(*p) && !valid_user_group_name_or_id(*p))
1102 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
1103 }
1104
1105 if (mode != UNIT_CHECK) {
1106 if (strv_length(l) == 0) {
1107 c->supplementary_groups = strv_free(c->supplementary_groups);
1108 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
1109 } else {
1110 _cleanup_free_ char *joined = NULL;
1111
1112 r = strv_extend_strv(&c->supplementary_groups, l, true);
1113 if (r < 0)
1114 return -ENOMEM;
1115
1116 joined = strv_join(c->supplementary_groups, " ");
1117 if (!joined)
1118 return -ENOMEM;
1119
1120 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
1121 }
1122 }
1123
1124 return 1;
1125
de53c417
EV
1126 } else if (streq(name, "SyslogIdentifier")) {
1127 const char *id;
c7040b5d 1128
de53c417
EV
1129 r = sd_bus_message_read(message, "s", &id);
1130 if (r < 0)
1131 return r;
1132
1133 if (mode != UNIT_CHECK) {
76736280
LP
1134
1135 if (isempty(id))
1136 c->syslog_identifier = mfree(c->syslog_identifier);
1137 else if (free_and_strdup(&c->syslog_identifier, id) < 0)
1138 return -ENOMEM;
de53c417 1139
b27b4b51 1140 unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s", id);
de53c417
EV
1141 }
1142
a8a13575
EV
1143 return 1;
1144 } else if (streq(name, "SyslogLevel")) {
8d1dd6ab 1145 int32_t level;
a8a13575
EV
1146
1147 r = sd_bus_message_read(message, "i", &level);
1148 if (r < 0)
1149 return r;
1150
e0d6e0fa
EV
1151 if (!log_level_is_valid(level))
1152 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
1153
a8a13575
EV
1154 if (mode != UNIT_CHECK) {
1155 c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
b27b4b51 1156 unit_write_drop_in_private_format(u, mode, name, "SyslogLevel=%i", level);
a8a13575
EV
1157 }
1158
460ed929
EV
1159 return 1;
1160 } else if (streq(name, "SyslogFacility")) {
8d1dd6ab 1161 int32_t facility;
460ed929
EV
1162
1163 r = sd_bus_message_read(message, "i", &facility);
1164 if (r < 0)
1165 return r;
1166
e0d6e0fa
EV
1167 if (!log_facility_unshifted_is_valid(facility))
1168 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
1169
460ed929
EV
1170 if (mode != UNIT_CHECK) {
1171 c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
b27b4b51 1172 unit_write_drop_in_private_format(u, mode, name, "SyslogFacility=%i", facility);
460ed929
EV
1173 }
1174
cffaed83 1175 return 1;
d3070fbd
LP
1176
1177 } else if (streq(name, "LogLevelMax")) {
1178 int32_t level;
1179
1180 r = sd_bus_message_read(message, "i", &level);
1181 if (r < 0)
1182 return r;
1183
1184 if (!log_level_is_valid(level))
1185 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Maximum log level value out of range");
1186
1187 if (mode != UNIT_CHECK) {
1188 c->log_level_max = level;
1189 unit_write_drop_in_private_format(u, mode, name, "LogLevelMax=%i", level);
1190 }
1191
1192 return 1;
1193
1194 } else if (streq(name, "LogExtraFields")) {
1195 size_t n = 0;
1196
1197 r = sd_bus_message_enter_container(message, 'a', "ay");
1198 if (r < 0)
1199 return r;
1200
1201 for (;;) {
1202 _cleanup_free_ void *copy = NULL;
1203 struct iovec *t;
1204 const char *eq;
1205 const void *p;
1206 size_t sz;
1207
1208 /* Note that we expect a byte array for each field, instead of a string. That's because on the
1209 * lower-level journal fields can actually contain binary data and are not restricted to text,
1210 * and we should not "lose precision" in our types on the way. That said, I am pretty sure
1211 * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
1212 * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
1213 * limitation, should a good, valid usecase arise. */
1214
1215 r = sd_bus_message_read_array(message, 'y', &p, &sz);
1216 if (r < 0)
1217 return r;
1218 if (r == 0)
1219 break;
1220
1221 if (memchr(p, 0, sz))
1222 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
1223
1224 eq = memchr(p, '=', sz);
1225 if (!eq)
1226 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
1227 if (!journal_field_valid(p, eq - (const char*) p, false))
1228 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
1229
1230 if (mode != UNIT_CHECK) {
1231 t = realloc_multiply(c->log_extra_fields, sizeof(struct iovec), c->n_log_extra_fields+1);
1232 if (!t)
1233 return -ENOMEM;
1234 c->log_extra_fields = t;
1235 }
1236
1237 copy = malloc(sz + 1);
1238 if (!copy)
1239 return -ENOMEM;
1240
1241 memcpy(copy, p, sz);
1242 ((uint8_t*) copy)[sz] = 0;
1243
1244 if (!utf8_is_valid(copy))
1245 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
1246
1247 if (mode != UNIT_CHECK) {
1248 c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
1249 unit_write_drop_in_private_format(u, mode, name, "LogExtraFields=%s", (char*) copy);
1250
1251 copy = NULL;
1252 }
1253
1254 n++;
1255 }
1256
1257 r = sd_bus_message_exit_container(message);
1258 if (r < 0)
1259 return r;
1260
1261 if (mode != UNIT_CHECK && n == 0) {
1262 exec_context_free_log_extra_fields(c);
1263 unit_write_drop_in_private(u, mode, name, "LogExtraFields=");
1264 }
1265
1266 return 1;
1267
cffaed83
YW
1268 } else if (streq(name, "SecureBits")) {
1269 int n;
1270
1271 r = sd_bus_message_read(message, "i", &n);
1272 if (r < 0)
1273 return r;
1274
1275 if (!secure_bits_is_valid(n))
1276 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits");
1277
1278 if (mode != UNIT_CHECK) {
1279 _cleanup_free_ char *str = NULL;
1280
1281 c->secure_bits = n;
1282 r = secure_bits_to_string_alloc(n, &str);
1283 if (r < 0)
1284 return r;
1285
1286 unit_write_drop_in_private_format(u, mode, name, "SecureBits=%s", str);
1287 }
1288
1289 return 1;
1290 } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) {
1291 uint64_t n;
1292
1293 r = sd_bus_message_read(message, "t", &n);
1294 if (r < 0)
1295 return r;
1296
1297 if (mode != UNIT_CHECK) {
1298 _cleanup_free_ char *str = NULL;
1299
1300 if (streq(name, "CapabilityBoundingSet"))
1301 c->capability_bounding_set = n;
1302 else /* "AmbientCapabilities" */
1303 c->capability_ambient_set = n;
1304
1305 r = capability_set_to_string_alloc(n, &str);
1306 if (r < 0)
1307 return r;
1308
1309 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str);
1310 }
1311
1312 return 1;
1313
1314 } else if (streq(name, "Personality")) {
1315 const char *s;
1316 unsigned long p;
1317
1318 r = sd_bus_message_read(message, "s", &s);
1319 if (r < 0)
1320 return r;
1321
1322 p = personality_from_string(s);
1323 if (p == PERSONALITY_INVALID)
1324 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality");
1325
1326 if (mode != UNIT_CHECK) {
cffaed83
YW
1327 c->personality = p;
1328 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
1329 }
1330
1331 return 1;
1332
349cc4a5 1333#if HAVE_SECCOMP
cffaed83
YW
1334
1335 } else if (streq(name, "SystemCallFilter")) {
1336 int whitelist;
3f856a28 1337 _cleanup_strv_free_ char **l = NULL;
cffaed83
YW
1338
1339 r = sd_bus_message_enter_container(message, 'r', "bas");
1340 if (r < 0)
1341 return r;
1342
1343 r = sd_bus_message_read(message, "b", &whitelist);
1344 if (r < 0)
1345 return r;
1346
1347 r = sd_bus_message_read_strv(message, &l);
1348 if (r < 0)
1349 return r;
1350
1351 r = sd_bus_message_exit_container(message);
1352 if (r < 0)
1353 return r;
1354
1355 if (mode != UNIT_CHECK) {
1356 _cleanup_free_ char *joined = NULL;
1357
1358 if (strv_length(l) == 0) {
1359 c->syscall_whitelist = false;
8cfa775f 1360 c->syscall_filter = hashmap_free(c->syscall_filter);
cffaed83
YW
1361 } else {
1362 char **s;
1363
1364 c->syscall_whitelist = whitelist;
1365
8cfa775f 1366 r = hashmap_ensure_allocated(&c->syscall_filter, NULL);
cffaed83
YW
1367 if (r < 0)
1368 return r;
1369
1370 STRV_FOREACH(s, l) {
8cfa775f
YW
1371 _cleanup_free_ char *n = NULL;
1372 int e;
1373
1374 r = parse_syscall_and_errno(*s, &n, &e);
1375 if (r < 0)
1376 return r;
1377
1378 if (*n == '@') {
cffaed83
YW
1379 const SyscallFilterSet *set;
1380 const char *i;
1381
8cfa775f 1382 set = syscall_filter_set_find(n);
cffaed83
YW
1383 if (!set)
1384 return -EINVAL;
1385
1386 NULSTR_FOREACH(i, set->value) {
1387 int id;
1388
1389 id = seccomp_syscall_resolve_name(i);
1390 if (id == __NR_SCMP_ERROR)
1391 return -EINVAL;
1392
8cfa775f 1393 r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e));
cffaed83
YW
1394 if (r < 0)
1395 return r;
1396 }
1397
1398 } else {
1399 int id;
1400
8cfa775f 1401 id = seccomp_syscall_resolve_name(n);
cffaed83
YW
1402 if (id == __NR_SCMP_ERROR)
1403 return -EINVAL;
1404
8cfa775f 1405 r = hashmap_put(c->syscall_filter, INT_TO_PTR(id + 1), INT_TO_PTR(e));
cffaed83
YW
1406 if (r < 0)
1407 return r;
1408 }
1409 }
1410 }
1411
1412 joined = strv_join(l, " ");
1413 if (!joined)
1414 return -ENOMEM;
1415
1416 unit_write_drop_in_private_format(u, mode, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
1417 }
1418
1419 return 1;
1420
1421 } else if (streq(name, "SystemCallArchitectures")) {
1422 _cleanup_strv_free_ char **l = NULL;
1423
1424 r = sd_bus_message_read_strv(message, &l);
1425 if (r < 0)
1426 return r;
1427
1428 if (mode != UNIT_CHECK) {
1429 _cleanup_free_ char *joined = NULL;
1430
1431 if (strv_length(l) == 0)
1432 c->syscall_archs = set_free(c->syscall_archs);
1433 else {
1434 char **s;
1435
1436 r = set_ensure_allocated(&c->syscall_archs, NULL);
1437 if (r < 0)
1438 return r;
1439
1440 STRV_FOREACH(s, l) {
1441 uint32_t a;
1442
1443 r = seccomp_arch_from_string(*s, &a);
1444 if (r < 0)
1445 return r;
1446
1447 r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
1448 if (r < 0)
1449 return r;
1450 }
1451
1452 }
1453
1454 joined = strv_join(l, " ");
1455 if (!joined)
1456 return -ENOMEM;
1457
1458 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
1459 }
1460
1461 return 1;
1462
1463 } else if (streq(name, "SystemCallErrorNumber")) {
1464 int32_t n;
cffaed83
YW
1465
1466 r = sd_bus_message_read(message, "i", &n);
1467 if (r < 0)
1468 return r;
1469
3df90f24 1470 if (n <= 0 || n > ERRNO_MAX)
cffaed83
YW
1471 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber");
1472
1473 if (mode != UNIT_CHECK) {
1474 c->syscall_errno = n;
1475
3df90f24 1476 unit_write_drop_in_private_format(u, mode, name, "SystemCallErrorNumber=%d", n);
cffaed83
YW
1477 }
1478
1479 return 1;
1480
1481 } else if (streq(name, "RestrictAddressFamilies")) {
1482 int whitelist;
3f856a28 1483 _cleanup_strv_free_ char **l = NULL;
cffaed83
YW
1484
1485 r = sd_bus_message_enter_container(message, 'r', "bas");
1486 if (r < 0)
1487 return r;
1488
1489 r = sd_bus_message_read(message, "b", &whitelist);
1490 if (r < 0)
1491 return r;
1492
1493 r = sd_bus_message_read_strv(message, &l);
1494 if (r < 0)
1495 return r;
1496
1497 r = sd_bus_message_exit_container(message);
1498 if (r < 0)
1499 return r;
1500
1501 if (mode != UNIT_CHECK) {
1502 _cleanup_free_ char *joined = NULL;
1503
1504 if (strv_length(l) == 0) {
1505 c->address_families_whitelist = false;
1506 c->address_families = set_free(c->address_families);
1507 } else {
1508 char **s;
1509
1510 c->address_families_whitelist = whitelist;
1511
1512 r = set_ensure_allocated(&c->address_families, NULL);
1513 if (r < 0)
1514 return r;
1515
1516 STRV_FOREACH(s, l) {
1517 int af;
1518
1519 af = af_from_name(*s);
1520 if (af <= 0)
1521 return -EINVAL;
1522
1523 r = set_put(c->address_families, INT_TO_PTR(af));
1524 if (r < 0)
1525 return r;
1526 }
1527 }
1528
1529 joined = strv_join(l, " ");
1530 if (!joined)
1531 return -ENOMEM;
1532
1533 unit_write_drop_in_private_format(u, mode, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
1534 }
1535
1536 return 1;
1537#endif
1538
1539 } else if (streq(name, "CPUSchedulingPolicy")) {
1540 int32_t n;
1541
1542 r = sd_bus_message_read(message, "i", &n);
1543 if (r < 0)
1544 return r;
1545
1546 if (!sched_policy_is_valid(n))
1547 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy");
1548
1549 if (mode != UNIT_CHECK) {
1550 _cleanup_free_ char *str = NULL;
1551
1552 c->cpu_sched_policy = n;
1553 r = sched_policy_to_string_alloc(n, &str);
1554 if (r < 0)
1555 return r;
1556
1557 unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPolicy=%s", str);
1558 }
1559
1560 return 1;
1561
1562 } else if (streq(name, "CPUSchedulingPriority")) {
1563 int32_t n;
1564
1565 r = sd_bus_message_read(message, "i", &n);
1566 if (r < 0)
1567 return r;
1568
1569 if (!ioprio_priority_is_valid(n))
1570 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority");
1571
1572 if (mode != UNIT_CHECK) {
1573 c->cpu_sched_priority = n;
1574 unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPriority=%i", n);
1575 }
1576
1577 return 1;
1578
1579 } else if (streq(name, "CPUAffinity")) {
1580 const void *a;
1581 size_t n = 0;
1582
1583 r = sd_bus_message_read_array(message, 'y', &a, &n);
1584 if (r < 0)
1585 return r;
1586
1587 if (mode != UNIT_CHECK) {
1588 if (n == 0) {
1589 c->cpuset = mfree(c->cpuset);
1590 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
1591 } else {
1592 _cleanup_free_ char *str = NULL;
1593 uint8_t *l;
1594 size_t allocated = 0, len = 0, i;
1595
1596 c->cpuset = (cpu_set_t*) memdup(a, sizeof(cpu_set_t) * n);
1597 if (c->cpuset)
1598 return -ENOMEM;
1599
1600 l = (uint8_t*) a;
1601 for (i = 0; i < n; i++) {
1602 _cleanup_free_ char *p = NULL;
1603 size_t add;
1604
1605 r = asprintf(&p, "%hhi", l[i]);
1606 if (r < 0)
1607 return -ENOMEM;
1608
1609 add = strlen(p);
1610
1611 if (GREEDY_REALLOC(str, allocated, len + add + 2))
1612 return -ENOMEM;
1613
1614 strcpy(mempcpy(str + len, p, add), " ");
1615 len += add + 1;
1616 }
1617
1618 if (len != 0)
1619 str[len - 1] = '\0';
1620
1621 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str);
1622 }
1623 }
1624
de53c417 1625 return 1;
c7040b5d 1626 } else if (streq(name, "Nice")) {
8d1dd6ab 1627 int32_t n;
c7040b5d
LP
1628
1629 r = sd_bus_message_read(message, "i", &n);
1630 if (r < 0)
1631 return r;
1632
41bf0590 1633 if (!nice_is_valid(n))
c7040b5d
LP
1634 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
1635
1636 if (mode != UNIT_CHECK) {
1637 c->nice = n;
b27b4b51 1638 unit_write_drop_in_private_format(u, mode, name, "Nice=%i", n);
c7040b5d
LP
1639 }
1640
1641 return 1;
1642
7f452159
LP
1643 } else if (streq(name, "IOSchedulingClass")) {
1644 int32_t q;
1645
1646 r = sd_bus_message_read(message, "i", &q);
1647 if (r < 0)
1648 return r;
1649
1650 if (!ioprio_class_is_valid(q))
1651 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
1652
1653 if (mode != UNIT_CHECK) {
1654 _cleanup_free_ char *s = NULL;
1655
1656 r = ioprio_class_to_string_alloc(q, &s);
1657 if (r < 0)
1658 return r;
1659
1660 c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
1661 c->ioprio_set = true;
1662
1663 unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
1664 }
1665
1666 return 1;
1667
1668 } else if (streq(name, "IOSchedulingPriority")) {
1669 int32_t p;
1670
1671 r = sd_bus_message_read(message, "i", &p);
1672 if (r < 0)
1673 return r;
1674
1675 if (!ioprio_priority_is_valid(p))
1676 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
1677
1678 if (mode != UNIT_CHECK) {
1679 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
1680 c->ioprio_set = true;
1681
1682 unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
1683 }
1684
1685 return 1;
1686
915e6d16 1687 } else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
602b8355 1688 const char *s;
9b15b784 1689
602b8355 1690 r = sd_bus_message_read(message, "s", &s);
9b15b784
LP
1691 if (r < 0)
1692 return r;
1693
602b8355
NC
1694 if (!path_is_absolute(s))
1695 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
9b15b784
LP
1696
1697 if (mode != UNIT_CHECK) {
5f5d8eab
LP
1698 if (streq(name, "TTYPath"))
1699 r = free_and_strdup(&c->tty_path, s);
915e6d16
LP
1700 else if (streq(name, "RootImage"))
1701 r = free_and_strdup(&c->root_image, s);
5f5d8eab
LP
1702 else {
1703 assert(streq(name, "RootDirectory"));
1704 r = free_and_strdup(&c->root_directory, s);
602b8355 1705 }
5f5d8eab
LP
1706 if (r < 0)
1707 return r;
9b15b784 1708
b27b4b51 1709 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
9b15b784
LP
1710 }
1711
1712 return 1;
1713
5f5d8eab
LP
1714 } else if (streq(name, "WorkingDirectory")) {
1715 const char *s;
1716 bool missing_ok;
1717
1718 r = sd_bus_message_read(message, "s", &s);
1719 if (r < 0)
1720 return r;
1721
1722 if (s[0] == '-') {
1723 missing_ok = true;
1724 s++;
1725 } else
1726 missing_ok = false;
1727
1728 if (!streq(s, "~") && !path_is_absolute(s))
1729 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
1730
1731 if (mode != UNIT_CHECK) {
1732 if (streq(s, "~")) {
1733 c->working_directory = mfree(c->working_directory);
1734 c->working_directory_home = true;
1735 } else {
1736 r = free_and_strdup(&c->working_directory, s);
1737 if (r < 0)
1738 return r;
1739
1740 c->working_directory_home = false;
1741 }
1742
1743 c->working_directory_missing_ok = missing_ok;
b27b4b51 1744 unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
5f5d8eab
LP
1745 }
1746
1747 return 1;
1748
9b15b784
LP
1749 } else if (streq(name, "StandardInput")) {
1750 const char *s;
1751 ExecInput p;
1752
1753 r = sd_bus_message_read(message, "s", &s);
1754 if (r < 0)
1755 return r;
1756
1757 p = exec_input_from_string(s);
1758 if (p < 0)
1759 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
1760
1761 if (mode != UNIT_CHECK) {
1762 c->std_input = p;
1763
b27b4b51 1764 unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s", exec_input_to_string(p));
9b15b784
LP
1765 }
1766
1767 return 1;
1768
9b15b784
LP
1769 } else if (streq(name, "StandardOutput")) {
1770 const char *s;
1771 ExecOutput p;
1772
1773 r = sd_bus_message_read(message, "s", &s);
1774 if (r < 0)
1775 return r;
1776
1777 p = exec_output_from_string(s);
1778 if (p < 0)
1779 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
1780
1781 if (mode != UNIT_CHECK) {
1782 c->std_output = p;
1783
b27b4b51 1784 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s", exec_output_to_string(p));
9b15b784
LP
1785 }
1786
1787 return 1;
1788
1789 } else if (streq(name, "StandardError")) {
1790 const char *s;
1791 ExecOutput p;
1792
1793 r = sd_bus_message_read(message, "s", &s);
1794 if (r < 0)
1795 return r;
1796
1797 p = exec_output_from_string(s);
1798 if (p < 0)
1799 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
1800
1801 if (mode != UNIT_CHECK) {
1802 c->std_error = p;
1803
b27b4b51 1804 unit_write_drop_in_private_format(u, mode, name, "StandardError=%s", exec_output_to_string(p));
9b15b784
LP
1805 }
1806
1807 return 1;
1808
52c239d7
LB
1809 } else if (STR_IN_SET(name,
1810 "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
1811 const char *s;
1812
1813 r = sd_bus_message_read(message, "s", &s);
1814 if (r < 0)
1815 return r;
1816
1817 if (!fdname_is_valid(s))
1818 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
1819
1820 if (mode != UNIT_CHECK) {
1821 if (streq(name, "StandardInputFileDescriptorName")) {
1822 c->std_input = EXEC_INPUT_NAMED_FD;
1823 r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], s);
1824 if (r < 0)
1825 return r;
1826 unit_write_drop_in_private_format(u, mode, name, "StandardInput=fd:%s", s);
1827 } else if (streq(name, "StandardOutputFileDescriptorName")) {
1828 c->std_output = EXEC_OUTPUT_NAMED_FD;
1829 r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], s);
1830 if (r < 0)
1831 return r;
1832 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=fd:%s", s);
1833 } else if (streq(name, "StandardErrorFileDescriptorName")) {
1834 c->std_error = EXEC_OUTPUT_NAMED_FD;
1835 r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s);
1836 if (r < 0)
1837 return r;
1838 unit_write_drop_in_private_format(u, mode, name, "StandardError=fd:%s", s);
1839 }
1840 }
1841
1842 return 1;
1843
b9c50073 1844 } else if (STR_IN_SET(name,
cffaed83 1845 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
d251207d 1846 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
29206d46 1847 "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
59eeb84b 1848 "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
cffaed83 1849 "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
3167f78a 1850 "CPUSchedulingResetOnFork", "NonBlocking", "LockPersonality")) {
506711fd
LP
1851 int b;
1852
1853 r = sd_bus_message_read(message, "b", &b);
1854 if (r < 0)
1855 return r;
1856
1857 if (mode != UNIT_CHECK) {
b9c50073
GP
1858 if (streq(name, "IgnoreSIGPIPE"))
1859 c->ignore_sigpipe = b;
1860 else if (streq(name, "TTYVHangup"))
1861 c->tty_vhangup = b;
1862 else if (streq(name, "TTYReset"))
1863 c->tty_reset = b;
cffaed83
YW
1864 else if (streq(name, "TTYVTDisallocate"))
1865 c->tty_vt_disallocate = b;
b9c50073
GP
1866 else if (streq(name, "PrivateTmp"))
1867 c->private_tmp = b;
1868 else if (streq(name, "PrivateDevices"))
1869 c->private_devices = b;
1870 else if (streq(name, "PrivateNetwork"))
1871 c->private_network = b;
d251207d
LP
1872 else if (streq(name, "PrivateUsers"))
1873 c->private_users = b;
b9c50073
GP
1874 else if (streq(name, "NoNewPrivileges"))
1875 c->no_new_privileges = b;
047d9933
EV
1876 else if (streq(name, "SyslogLevelPrefix"))
1877 c->syslog_level_prefix = b;
f3e43635
TM
1878 else if (streq(name, "MemoryDenyWriteExecute"))
1879 c->memory_deny_write_execute = b;
f4170c67
LP
1880 else if (streq(name, "RestrictRealtime"))
1881 c->restrict_realtime = b;
29206d46
LP
1882 else if (streq(name, "DynamicUser"))
1883 c->dynamic_user = b;
00d9ef85
LP
1884 else if (streq(name, "RemoveIPC"))
1885 c->remove_ipc = b;
59eeb84b
LP
1886 else if (streq(name, "ProtectKernelTunables"))
1887 c->protect_kernel_tunables = b;
502d704e
DH
1888 else if (streq(name, "ProtectKernelModules"))
1889 c->protect_kernel_modules = b;
59eeb84b
LP
1890 else if (streq(name, "ProtectControlGroups"))
1891 c->protect_control_groups = b;
5d997827
LP
1892 else if (streq(name, "MountAPIVFS"))
1893 c->mount_apivfs = b;
cffaed83
YW
1894 else if (streq(name, "CPUSchedulingResetOnFork"))
1895 c->cpu_sched_reset_on_fork = b;
1896 else if (streq(name, "NonBlocking"))
1897 c->non_blocking = b;
3167f78a
LP
1898 else if (streq(name, "LockPersonality"))
1899 c->lock_personality = b;
b9c50073 1900
b27b4b51 1901 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, yes_no(b));
506711fd
LP
1902 }
1903
1904 return 1;
1905
1906 } else if (streq(name, "UtmpIdentifier")) {
1907 const char *id;
1908
1909 r = sd_bus_message_read(message, "s", &id);
1910 if (r < 0)
1911 return r;
1912
1913 if (mode != UNIT_CHECK) {
76736280
LP
1914 if (isempty(id))
1915 c->utmp_id = mfree(c->utmp_id);
1916 else if (free_and_strdup(&c->utmp_id, id) < 0)
1917 return -ENOMEM;
506711fd 1918
b27b4b51 1919 unit_write_drop_in_private_format(u, mode, name, "UtmpIdentifier=%s", strempty(id));
506711fd
LP
1920 }
1921
1922 return 1;
1923
1924 } else if (streq(name, "UtmpMode")) {
1925 const char *s;
1926 ExecUtmpMode m;
1927
1928 r = sd_bus_message_read(message, "s", &s);
1929 if (r < 0)
1930 return r;
1931
1932 m = exec_utmp_mode_from_string(s);
1933 if (m < 0)
1934 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
1935
1936 if (mode != UNIT_CHECK) {
1937 c->utmp_mode = m;
1938
b27b4b51 1939 unit_write_drop_in_private_format(u, mode, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
506711fd
LP
1940 }
1941
1942 return 1;
1943
1944 } else if (streq(name, "PAMName")) {
1945 const char *n;
1946
1947 r = sd_bus_message_read(message, "s", &n);
1948 if (r < 0)
1949 return r;
1950
1951 if (mode != UNIT_CHECK) {
76736280
LP
1952 if (isempty(n))
1953 c->pam_name = mfree(c->pam_name);
1954 else if (free_and_strdup(&c->pam_name, n) < 0)
1955 return -ENOMEM;
506711fd 1956
b27b4b51 1957 unit_write_drop_in_private_format(u, mode, name, "PAMName=%s", strempty(n));
506711fd
LP
1958 }
1959
1960 return 1;
1961
c7040b5d
LP
1962 } else if (streq(name, "Environment")) {
1963
f900f582 1964 _cleanup_strv_free_ char **l = NULL, **q = NULL;
c7040b5d
LP
1965
1966 r = sd_bus_message_read_strv(message, &l);
1967 if (r < 0)
1968 return r;
1969
f900f582
ZJS
1970 r = unit_full_printf_strv(u, l, &q);
1971 if (r < 0)
1972 return r;
c7040b5d 1973
1c68232e
LP
1974 if (!strv_env_is_valid(q))
1975 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
1976
f900f582
ZJS
1977 if (mode != UNIT_CHECK) {
1978 if (strv_length(q) == 0) {
e9876fc9 1979 c->environment = strv_free(c->environment);
b27b4b51 1980 unit_write_drop_in_private_format(u, mode, name, "Environment=");
e9876fc9 1981 } else {
f900f582
ZJS
1982 _cleanup_free_ char *joined = NULL;
1983 char **e;
1984
1985 e = strv_env_merge(2, c->environment, q);
e9876fc9
EV
1986 if (!e)
1987 return -ENOMEM;
c7040b5d 1988
e9876fc9
EV
1989 strv_free(c->environment);
1990 c->environment = e;
c7040b5d 1991
f900f582 1992 /* We write just the new settings out to file, with unresolved specifiers */
1c68232e 1993 joined = strv_join_quoted(l);
e9876fc9
EV
1994 if (!joined)
1995 return -ENOMEM;
1996
b27b4b51 1997 unit_write_drop_in_private_format(u, mode, name, "Environment=%s", joined);
e9876fc9 1998 }
c7040b5d
LP
1999 }
2000
d584f638
LP
2001 return 1;
2002
00819cc1
LP
2003 } else if (streq(name, "UnsetEnvironment")) {
2004
2005 _cleanup_strv_free_ char **l = NULL, **q = NULL;
2006
2007 r = sd_bus_message_read_strv(message, &l);
2008 if (r < 0)
2009 return r;
2010
2011 r = unit_full_printf_strv(u, l, &q);
2012 if (r < 0)
2013 return r;
2014
2015 if (!strv_env_name_or_assignment_is_valid(q))
2016 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
2017
2018 if (mode != UNIT_CHECK) {
2019 if (strv_length(q) == 0) {
2020 c->unset_environment = strv_free(c->unset_environment);
2021 unit_write_drop_in_private_format(u, mode, name, "UnsetEnvironment=");
2022 } else {
2023 _cleanup_free_ char *joined = NULL;
2024 char **e;
2025
2026 e = strv_env_merge(2, c->unset_environment, q);
2027 if (!e)
2028 return -ENOMEM;
2029
2030 strv_free(c->unset_environment);
2031 c->unset_environment = e;
2032
2033 /* We write just the new settings out to file, with unresolved specifiers */
2034 joined = strv_join_quoted(l);
2035 if (!joined)
2036 return -ENOMEM;
2037
2038 unit_write_drop_in_private_format(u, mode, name, "UnsetEnvironment=%s", joined);
2039 }
2040 }
2041
2042 return 1;
2043
f1db3327
EV
2044 } else if (streq(name, "TimerSlackNSec")) {
2045
2046 nsec_t n;
2047
2048 r = sd_bus_message_read(message, "t", &n);
2049 if (r < 0)
2050 return r;
2051
2052 if (mode != UNIT_CHECK) {
2053 c->timer_slack_nsec = n;
b27b4b51 2054 unit_write_drop_in_private_format(u, mode, name, "TimerSlackNSec=" NSEC_FMT, n);
f1db3327
EV
2055 }
2056
2057 return 1;
2058
6b862936
EV
2059 } else if (streq(name, "OOMScoreAdjust")) {
2060 int oa;
2061
2062 r = sd_bus_message_read(message, "i", &oa);
2063 if (r < 0)
2064 return r;
2065
2066 if (!oom_score_adjust_is_valid(oa))
2067 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
2068
2069 if (mode != UNIT_CHECK) {
2070 c->oom_score_adjust = oa;
2071 c->oom_score_adjust_set = true;
b27b4b51 2072 unit_write_drop_in_private_format(u, mode, name, "OOMScoreAdjust=%i", oa);
6b862936
EV
2073 }
2074
2075 return 1;
2076
ceb728cf
NC
2077 } else if (streq(name, "EnvironmentFiles")) {
2078
2079 _cleanup_free_ char *joined = NULL;
2080 _cleanup_fclose_ FILE *f = NULL;
9b531f04 2081 _cleanup_strv_free_ char **l = NULL;
ceb728cf 2082 size_t size = 0;
2229f656 2083 char **i;
ceb728cf
NC
2084
2085 r = sd_bus_message_enter_container(message, 'a', "(sb)");
2086 if (r < 0)
2087 return r;
2088
2089 f = open_memstream(&joined, &size);
2090 if (!f)
2091 return -ENOMEM;
2092
2229f656 2093 STRV_FOREACH(i, c->environment_files)
b27b4b51 2094 fprintf(f, "EnvironmentFile=%s", *i);
ceb728cf
NC
2095
2096 while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
2097 const char *path;
2098 int b;
2099
ceb728cf
NC
2100 r = sd_bus_message_read(message, "sb", &path, &b);
2101 if (r < 0)
2102 return r;
2103
2104 r = sd_bus_message_exit_container(message);
2105 if (r < 0)
2106 return r;
2107
d2d6c096
LP
2108 if (!path_is_absolute(path))
2109 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
ceb728cf
NC
2110
2111 if (mode != UNIT_CHECK) {
ae978b9f 2112 char *buf;
ceb728cf 2113
605405c6 2114 buf = strjoin(b ? "-" : "", path);
2229f656 2115 if (!buf)
ceb728cf
NC
2116 return -ENOMEM;
2117
b27b4b51 2118 fprintf(f, "EnvironmentFile=%s", buf);
ceb728cf 2119
2229f656 2120 r = strv_consume(&l, buf);
ceb728cf
NC
2121 if (r < 0)
2122 return r;
2123 }
2124 }
2125 if (r < 0)
2126 return r;
2127
b0830e21
LP
2128 r = sd_bus_message_exit_container(message);
2129 if (r < 0)
2130 return r;
2131
2229f656
LP
2132 r = fflush_and_check(f);
2133 if (r < 0)
2134 return r;
ceb728cf 2135
2229f656
LP
2136 if (mode != UNIT_CHECK) {
2137 if (strv_isempty(l)) {
2138 c->environment_files = strv_free(c->environment_files);
b27b4b51 2139 unit_write_drop_in_private(u, mode, name, "EnvironmentFile=");
2229f656
LP
2140 } else {
2141 r = strv_extend_strv(&c->environment_files, l, true);
2142 if (r < 0)
2143 return r;
2144
ceb728cf 2145 unit_write_drop_in_private(u, mode, name, joined);
2229f656
LP
2146 }
2147 }
ceb728cf 2148
ceb728cf
NC
2149 return 1;
2150
b4c14404
FB
2151 } else if (streq(name, "PassEnvironment")) {
2152
41de9cc2 2153 _cleanup_strv_free_ char **l = NULL, **q = NULL;
b4c14404
FB
2154
2155 r = sd_bus_message_read_strv(message, &l);
2156 if (r < 0)
2157 return r;
2158
41de9cc2
LP
2159 r = unit_full_printf_strv(u, l, &q);
2160 if (r < 0)
2161 return r;
2162
2163 if (!strv_env_name_is_valid(q))
00819cc1 2164 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
b4c14404
FB
2165
2166 if (mode != UNIT_CHECK) {
2167 if (strv_isempty(l)) {
2168 c->pass_environment = strv_free(c->pass_environment);
b27b4b51 2169 unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=");
b4c14404
FB
2170 } else {
2171 _cleanup_free_ char *joined = NULL;
2172
41de9cc2 2173 r = strv_extend_strv(&c->pass_environment, q, true);
b4c14404
FB
2174 if (r < 0)
2175 return r;
2176
41de9cc2
LP
2177 /* We write just the new settings out to file, with unresolved specifiers. */
2178 joined = strv_join_quoted(l);
b4c14404
FB
2179 if (!joined)
2180 return -ENOMEM;
2181
b27b4b51 2182 unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=%s", joined);
b4c14404
FB
2183 }
2184 }
2185
2186 return 1;
2187
2a624c36
AP
2188 } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
2189 "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
08596068
EV
2190 _cleanup_strv_free_ char **l = NULL;
2191 char ***dirs;
2192 char **p;
2193
2194 r = sd_bus_message_read_strv(message, &l);
2195 if (r < 0)
2196 return r;
2197
2198 STRV_FOREACH(p, l) {
20b7a007
LP
2199 const char *i = *p;
2200 size_t offset;
2201
2202 if (!utf8_is_valid(i))
08596068
EV
2203 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
2204
20b7a007
LP
2205 offset = i[0] == '-';
2206 offset += i[offset] == '+';
2207 if (!path_is_absolute(i + offset))
08596068
EV
2208 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
2209 }
2210
2211 if (mode != UNIT_CHECK) {
2212 _cleanup_free_ char *joined = NULL;
2213
c4b41707
AP
2214 if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
2215 dirs = &c->read_write_paths;
2216 else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
2217 dirs = &c->read_only_paths;
2218 else /* "InaccessiblePaths" */
2219 dirs = &c->inaccessible_paths;
08596068
EV
2220
2221 if (strv_length(l) == 0) {
2222 *dirs = strv_free(*dirs);
b27b4b51 2223 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
08596068
EV
2224 } else {
2225 r = strv_extend_strv(dirs, l, true);
08596068
EV
2226 if (r < 0)
2227 return -ENOMEM;
2228
2229 joined = strv_join_quoted(*dirs);
2230 if (!joined)
2231 return -ENOMEM;
2232
b27b4b51 2233 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
08596068
EV
2234 }
2235
2236 }
2237
2238 return 1;
2239
5664e6cf
EV
2240 } else if (streq(name, "ProtectSystem")) {
2241 const char *s;
2242 ProtectSystem ps;
2243
2244 r = sd_bus_message_read(message, "s", &s);
2245 if (r < 0)
2246 return r;
2247
2248 r = parse_boolean(s);
2249 if (r > 0)
2250 ps = PROTECT_SYSTEM_YES;
2251 else if (r == 0)
2252 ps = PROTECT_SYSTEM_NO;
2253 else {
2254 ps = protect_system_from_string(s);
2255 if (ps < 0)
2256 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value");
2257 }
2258
2259 if (mode != UNIT_CHECK) {
2260 c->protect_system = ps;
b27b4b51 2261 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
5664e6cf
EV
2262 }
2263
2264 return 1;
2265
eff58074
EV
2266 } else if (streq(name, "ProtectHome")) {
2267 const char *s;
2268 ProtectHome ph;
2269
2270 r = sd_bus_message_read(message, "s", &s);
2271 if (r < 0)
2272 return r;
2273
2274 r = parse_boolean(s);
2275 if (r > 0)
2276 ph = PROTECT_HOME_YES;
2277 else if (r == 0)
2278 ph = PROTECT_HOME_NO;
2279 else {
2280 ph = protect_home_from_string(s);
2281 if (ph < 0)
2282 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value");
2283 }
2284
2285 if (mode != UNIT_CHECK) {
2286 c->protect_home = ph;
b27b4b51 2287 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
eff58074
EV
2288 }
2289
2290 return 1;
2291
b1edf445
LP
2292 } else if (streq(name, "KeyringMode")) {
2293
2294 const char *s;
2295 ExecKeyringMode m;
2296
2297 r = sd_bus_message_read(message, "s", &s);
2298 if (r < 0)
2299 return r;
2300
2301 m = exec_keyring_mode_from_string(s);
2302 if (m < 0)
61ceaea5 2303 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid keyring mode");
b1edf445
LP
2304
2305 if (mode != UNIT_CHECK) {
2306 c->keyring_mode = m;
2307
2308 unit_write_drop_in_private_format(u, mode, name, "KeyringMode=%s", exec_keyring_mode_to_string(m));
2309 }
2310
2311 return 1;
2312
53f47dfc
YW
2313 } else if (streq(name, "RuntimeDirectoryPreserve")) {
2314 const char *s;
2315 ExecPreserveMode m;
2316
2317 r = sd_bus_message_read(message, "s", &s);
2318 if (r < 0)
2319 return r;
2320
2321 m = exec_preserve_mode_from_string(s);
2322 if (m < 0)
2323 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode");
2324
2325 if (mode != UNIT_CHECK) {
2326 c->runtime_directory_preserve_mode = m;
2327
2328 unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
2329 }
2330
2331 return 1;
2332
cffaed83 2333 } else if (STR_IN_SET(name, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) {
53f47dfc
YW
2334 mode_t m;
2335
2336 r = sd_bus_message_read(message, "u", &m);
2337 if (r < 0)
2338 return r;
2339
2340 if (mode != UNIT_CHECK) {
3536f49e 2341 ExecDirectoryType i;
53f47dfc 2342
cffaed83
YW
2343 if (streq(name, "UMask"))
2344 c->umask = m;
2345 else
72fd1768 2346 for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
cffaed83
YW
2347 if (startswith(name, exec_directory_type_to_string(i))) {
2348 c->directories[i].mode = m;
2349 break;
2350 }
3536f49e
YW
2351
2352 unit_write_drop_in_private_format(u, mode, name, "%s=%040o", name, m);
53f47dfc
YW
2353 }
2354
2355 return 1;
2356
3536f49e 2357 } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
fa21b5e3
EV
2358 _cleanup_strv_free_ char **l = NULL;
2359 char **p;
2360
2361 r = sd_bus_message_read_strv(message, &l);
2362 if (r < 0)
2363 return r;
2364
2365 STRV_FOREACH(p, l) {
091e9efe
LP
2366 if (!path_is_safe(*p) || path_is_absolute(*p))
2367 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not valid: %s", name, *p);
fa21b5e3
EV
2368 }
2369
2370 if (mode != UNIT_CHECK) {
2371 _cleanup_free_ char *joined = NULL;
3536f49e
YW
2372 char ***dirs = NULL;
2373 ExecDirectoryType i;
2374
72fd1768 2375 for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
3536f49e
YW
2376 if (streq(name, exec_directory_type_to_string(i))) {
2377 dirs = &c->directories[i].paths;
2378 break;
2379 }
2380
2381 assert(dirs);
fa21b5e3
EV
2382
2383 if (strv_isempty(l)) {
3536f49e 2384 *dirs = strv_free(*dirs);
b27b4b51 2385 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
fa21b5e3 2386 } else {
3536f49e 2387 r = strv_extend_strv(dirs, l, true);
fa21b5e3
EV
2388 if (r < 0)
2389 return -ENOMEM;
2390
3536f49e 2391 joined = strv_join_quoted(*dirs);
fa21b5e3
EV
2392 if (!joined)
2393 return -ENOMEM;
2394
b27b4b51 2395 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
fa21b5e3
EV
2396 }
2397 }
2398
2399 return 1;
2400
186ad4b1
JB
2401 } else if (streq(name, "SELinuxContext")) {
2402 const char *s;
186ad4b1
JB
2403 r = sd_bus_message_read(message, "s", &s);
2404 if (r < 0)
2405 return r;
2406
2407 if (mode != UNIT_CHECK) {
4e282d11
JB
2408 if (isempty(s))
2409 c->selinux_context = mfree(c->selinux_context);
2410 else if (free_and_strdup(&c->selinux_context, s) < 0)
2411 return -ENOMEM;
186ad4b1 2412
b27b4b51 2413 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, strempty(s));
186ad4b1
JB
2414 }
2415
2416 return 1;
cffaed83
YW
2417
2418 } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
2419 int ignore;
2420 const char *s;
2421
2422 r = sd_bus_message_enter_container(message, 'r', "bs");
2423 if (r < 0)
2424 return r;
2425
2426 r = sd_bus_message_read(message, "bs", &ignore, &s);
2427 if (r < 0)
2428 return r;
2429
2430 if (mode != UNIT_CHECK) {
2431 char **p;
2432 bool *b;
2433
2434 if (streq(name, "AppArmorProfile")) {
2435 p = &c->apparmor_profile;
2436 b = &c->apparmor_profile_ignore;
2437 } else { /* "SmackProcessLabel" */
2438 p = &c->smack_process_label;
2439 b = &c->smack_process_label_ignore;
2440 }
2441
2442 if (isempty(s)) {
2443 *p = mfree(*p);
2444 *b = false;
2445 } else {
2446 if (free_and_strdup(p, s) < 0)
2447 return -ENOMEM;
2448 *b = ignore;
2449 }
2450
2451 unit_write_drop_in_private_format(u, mode, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
2452 }
2453
2454 return 1;
2455
add00535
LP
2456 } else if (streq(name, "RestrictNamespaces")) {
2457 uint64_t flags;
186ad4b1 2458
add00535
LP
2459 r = sd_bus_message_read(message, "t", &flags);
2460 if (r < 0)
2461 return r;
2462 if ((flags & NAMESPACE_FLAGS_ALL) != flags)
2463 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
2464
2465 if (mode != UNIT_CHECK) {
2466 _cleanup_free_ char *s = NULL;
2467
2468 r = namespace_flag_to_string_many(flags, &s);
2469 if (r < 0)
2470 return r;
2471
2472 c->restrict_namespaces = flags;
2473 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
2474 }
2475
2476 return 1;
83555251
LP
2477 } else if (streq(name, "MountFlags")) {
2478 uint64_t flags;
2479
2480 r = sd_bus_message_read(message, "t", &flags);
2481 if (r < 0)
2482 return r;
2483 if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
2484 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
cab2aca3 2485
83555251
LP
2486 if (mode != UNIT_CHECK) {
2487 c->mount_flags = flags;
2488
c7383828 2489 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, mount_propagation_flags_to_string(flags));
83555251
LP
2490 }
2491
d2d6c096
LP
2492 return 1;
2493 } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
2494 unsigned empty = true;
2495
2496 r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
2497 if (r < 0)
2498 return r;
2499
2500 while ((r = sd_bus_message_enter_container(message, 'r', "ssbt")) > 0) {
2501 const char *source, *destination;
2502 int ignore_enoent;
2503 uint64_t mount_flags;
2504
2505 r = sd_bus_message_read(message, "ssbt", &source, &destination, &ignore_enoent, &mount_flags);
2506 if (r < 0)
2507 return r;
2508
2509 r = sd_bus_message_exit_container(message);
2510 if (r < 0)
2511 return r;
2512
2513 if (!path_is_absolute(source))
2514 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
2515 if (!path_is_absolute(destination))
91d910e3 2516 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
d2d6c096
LP
2517 if (!IN_SET(mount_flags, 0, MS_REC))
2518 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
2519
2520 if (mode != UNIT_CHECK) {
2521 r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
2522 &(BindMount) {
2523 .source = strdup(source),
2524 .destination = strdup(destination),
2525 .read_only = !!strstr(name, "ReadOnly"),
2526 .recursive = !!(mount_flags & MS_REC),
2527 .ignore_enoent = ignore_enoent,
2528 });
2529 if (r < 0)
2530 return r;
2531
2532 unit_write_drop_in_private_format(
2533 u, mode, name,
2534 "%s=%s%s:%s:%s",
2535 name,
2536 ignore_enoent ? "-" : "",
2537 source,
2538 destination,
2539 (mount_flags & MS_REC) ? "rbind" : "norbind");
2540 }
2541
2542 empty = false;
2543 }
2544 if (r < 0)
2545 return r;
2546
2547 r = sd_bus_message_exit_container(message);
2548 if (r < 0)
2549 return r;
2550
2551 if (empty) {
2552 bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
2553 c->bind_mounts = NULL;
2554 c->n_bind_mounts = 0;
2555 }
2556
83555251
LP
2557 return 1;
2558 }
d2d6c096 2559
cab2aca3
LP
2560 ri = rlimit_from_string(name);
2561 if (ri < 0) {
2562 soft = endswith(name, "Soft");
2563 if (soft) {
2564 const char *n;
2565
2566 n = strndupa(name, soft - name);
2567 ri = rlimit_from_string(n);
2568 if (ri >= 0)
2569 name = n;
2570
2571 }
2572 }
2573
2574 if (ri >= 0) {
d584f638
LP
2575 uint64_t rl;
2576 rlim_t x;
2577
2578 r = sd_bus_message_read(message, "t", &rl);
2579 if (r < 0)
2580 return r;
2581
2582 if (rl == (uint64_t) -1)
2583 x = RLIM_INFINITY;
2584 else {
2585 x = (rlim_t) rl;
2586
2587 if ((uint64_t) x != rl)
2588 return -ERANGE;
2589 }
2590
2591 if (mode != UNIT_CHECK) {
cab2aca3
LP
2592 _cleanup_free_ char *f = NULL;
2593 struct rlimit nl;
2594
2595 if (c->rlimit[ri]) {
2596 nl = *c->rlimit[ri];
2597
2598 if (soft)
2599 nl.rlim_cur = x;
2600 else
2601 nl.rlim_max = x;
2602 } else
2603 /* When the resource limit is not initialized yet, then assign the value to both fields */
2604 nl = (struct rlimit) {
2605 .rlim_cur = x,
2606 .rlim_max = x,
2607 };
2608
2609 r = rlimit_format(&nl, &f);
2610 if (r < 0)
2611 return r;
d584f638 2612
cab2aca3
LP
2613 if (c->rlimit[ri])
2614 *c->rlimit[ri] = nl;
2615 else {
2616 c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
2617 if (!c->rlimit[ri])
d584f638
LP
2618 return -ENOMEM;
2619 }
2620
b27b4b51 2621 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, f);
d584f638
LP
2622 }
2623
c7040b5d
LP
2624 return 1;
2625 }
2626
2627 return 0;
2628}