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