]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
Add hwdb fix for Lenovo Flex 3 15 inch touchpad resolution (#6558)
[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),
4298d0b5 856 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
53f47dfc 857 SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
3536f49e
YW
858 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
859 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].paths), SD_BUS_VTABLE_PROPERTY_CONST),
e940c1ef
YW
860 SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
861 SD_BUS_PROPERTY("StateDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
3536f49e
YW
862 SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
863 SD_BUS_PROPERTY("CacheDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
864 SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
865 SD_BUS_PROPERTY("LogsDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].paths), SD_BUS_VTABLE_PROPERTY_CONST),
866 SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
867 SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST),
f3e43635 868 SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
f4170c67 869 SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
6a8c2d59 870 SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
d2d6c096
LP
871 SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
872 SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
5d997827 873 SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
7f452159
LP
874
875 /* Obsolete/redundant properties: */
876 SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
877 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
878 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
879 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
880 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
881
718db961
LP
882 SD_BUS_VTABLE_END
883};
82c121a4 884
4d4c80d0
LP
885static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
886 int r;
887
888 assert(reply);
889 assert(c);
890
891 if (!c->path)
892 return 0;
893
894 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
895 if (r < 0)
896 return r;
897
898 r = sd_bus_message_append(reply, "s", c->path);
899 if (r < 0)
900 return r;
901
902 r = sd_bus_message_append_strv(reply, c->argv);
903 if (r < 0)
904 return r;
905
906 r = sd_bus_message_append(reply, "bttttuii",
907 c->ignore,
908 c->exec_status.start_timestamp.realtime,
909 c->exec_status.start_timestamp.monotonic,
910 c->exec_status.exit_timestamp.realtime,
911 c->exec_status.exit_timestamp.monotonic,
912 (uint32_t) c->exec_status.pid,
913 (int32_t) c->exec_status.code,
914 (int32_t) c->exec_status.status);
915 if (r < 0)
916 return r;
917
918 return sd_bus_message_close_container(reply);
919}
920
718db961
LP
921int bus_property_get_exec_command(
922 sd_bus *bus,
923 const char *path,
924 const char *interface,
925 const char *property,
926 sd_bus_message *reply,
ebcf1f97
LP
927 void *userdata,
928 sd_bus_error *ret_error) {
fe68089d 929
4d4c80d0 930 ExecCommand *c = (ExecCommand*) userdata;
718db961 931 int r;
fe68089d 932
718db961
LP
933 assert(bus);
934 assert(reply);
fe68089d 935
718db961
LP
936 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
937 if (r < 0)
938 return r;
fe68089d 939
4d4c80d0
LP
940 r = append_exec_command(reply, c);
941 if (r < 0)
942 return r;
fe68089d 943
4d4c80d0
LP
944 return sd_bus_message_close_container(reply);
945}
718db961 946
4d4c80d0
LP
947int bus_property_get_exec_command_list(
948 sd_bus *bus,
949 const char *path,
950 const char *interface,
951 const char *property,
952 sd_bus_message *reply,
953 void *userdata,
954 sd_bus_error *ret_error) {
718db961 955
4d4c80d0
LP
956 ExecCommand *c = *(ExecCommand**) userdata;
957 int r;
718db961 958
4d4c80d0
LP
959 assert(bus);
960 assert(reply);
961
962 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
963 if (r < 0)
964 return r;
718db961 965
4d4c80d0
LP
966 LIST_FOREACH(command, c, c) {
967 r = append_exec_command(reply, c);
718db961
LP
968 if (r < 0)
969 return r;
fe68089d
LP
970 }
971
718db961 972 return sd_bus_message_close_container(reply);
8351ceae 973}
c7040b5d
LP
974
975int bus_exec_context_set_transient_property(
976 Unit *u,
977 ExecContext *c,
978 const char *name,
979 sd_bus_message *message,
980 UnitSetPropertiesMode mode,
981 sd_bus_error *error) {
982
cab2aca3
LP
983 const char *soft = NULL;
984 int r, ri;
c7040b5d
LP
985
986 assert(u);
987 assert(c);
988 assert(name);
989 assert(message);
990
991 if (streq(name, "User")) {
992 const char *uu;
993
994 r = sd_bus_message_read(message, "s", &uu);
995 if (r < 0)
996 return r;
997
6f3e7985
LP
998 if (!isempty(uu) && !valid_user_group_name_or_id(uu))
999 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu);
1000
c7040b5d 1001 if (mode != UNIT_CHECK) {
76736280
LP
1002
1003 if (isempty(uu))
1004 c->user = mfree(c->user);
1005 else if (free_and_strdup(&c->user, uu) < 0)
1006 return -ENOMEM;
c7040b5d 1007
b27b4b51 1008 unit_write_drop_in_private_format(u, mode, name, "User=%s", uu);
c7040b5d
LP
1009 }
1010
1011 return 1;
1012
1013 } else if (streq(name, "Group")) {
1014 const char *gg;
1015
1016 r = sd_bus_message_read(message, "s", &gg);
1017 if (r < 0)
1018 return r;
1019
6f3e7985
LP
1020 if (!isempty(gg) && !valid_user_group_name_or_id(gg))
1021 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg);
1022
c7040b5d 1023 if (mode != UNIT_CHECK) {
76736280
LP
1024
1025 if (isempty(gg))
1026 c->group = mfree(c->group);
1027 else if (free_and_strdup(&c->group, gg) < 0)
1028 return -ENOMEM;
c7040b5d 1029
b27b4b51 1030 unit_write_drop_in_private_format(u, mode, name, "Group=%s", gg);
c7040b5d
LP
1031 }
1032
1033 return 1;
cffaed83
YW
1034
1035 } else if (streq(name, "SupplementaryGroups")) {
1036 _cleanup_strv_free_ char **l = NULL;
1037 char **p;
1038
1039 r = sd_bus_message_read_strv(message, &l);
1040 if (r < 0)
1041 return r;
1042
1043 STRV_FOREACH(p, l) {
1044 if (!isempty(*p) && !valid_user_group_name_or_id(*p))
1045 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
1046 }
1047
1048 if (mode != UNIT_CHECK) {
1049 if (strv_length(l) == 0) {
1050 c->supplementary_groups = strv_free(c->supplementary_groups);
1051 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
1052 } else {
1053 _cleanup_free_ char *joined = NULL;
1054
1055 r = strv_extend_strv(&c->supplementary_groups, l, true);
1056 if (r < 0)
1057 return -ENOMEM;
1058
1059 joined = strv_join(c->supplementary_groups, " ");
1060 if (!joined)
1061 return -ENOMEM;
1062
1063 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
1064 }
1065 }
1066
1067 return 1;
1068
de53c417
EV
1069 } else if (streq(name, "SyslogIdentifier")) {
1070 const char *id;
c7040b5d 1071
de53c417
EV
1072 r = sd_bus_message_read(message, "s", &id);
1073 if (r < 0)
1074 return r;
1075
1076 if (mode != UNIT_CHECK) {
76736280
LP
1077
1078 if (isempty(id))
1079 c->syslog_identifier = mfree(c->syslog_identifier);
1080 else if (free_and_strdup(&c->syslog_identifier, id) < 0)
1081 return -ENOMEM;
de53c417 1082
b27b4b51 1083 unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s", id);
de53c417
EV
1084 }
1085
a8a13575
EV
1086 return 1;
1087 } else if (streq(name, "SyslogLevel")) {
8d1dd6ab 1088 int32_t level;
a8a13575
EV
1089
1090 r = sd_bus_message_read(message, "i", &level);
1091 if (r < 0)
1092 return r;
1093
e0d6e0fa
EV
1094 if (!log_level_is_valid(level))
1095 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
1096
a8a13575
EV
1097 if (mode != UNIT_CHECK) {
1098 c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
b27b4b51 1099 unit_write_drop_in_private_format(u, mode, name, "SyslogLevel=%i", level);
a8a13575
EV
1100 }
1101
460ed929
EV
1102 return 1;
1103 } else if (streq(name, "SyslogFacility")) {
8d1dd6ab 1104 int32_t facility;
460ed929
EV
1105
1106 r = sd_bus_message_read(message, "i", &facility);
1107 if (r < 0)
1108 return r;
1109
e0d6e0fa
EV
1110 if (!log_facility_unshifted_is_valid(facility))
1111 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
1112
460ed929
EV
1113 if (mode != UNIT_CHECK) {
1114 c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
b27b4b51 1115 unit_write_drop_in_private_format(u, mode, name, "SyslogFacility=%i", facility);
460ed929
EV
1116 }
1117
cffaed83
YW
1118 return 1;
1119 } else if (streq(name, "SecureBits")) {
1120 int n;
1121
1122 r = sd_bus_message_read(message, "i", &n);
1123 if (r < 0)
1124 return r;
1125
1126 if (!secure_bits_is_valid(n))
1127 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits");
1128
1129 if (mode != UNIT_CHECK) {
1130 _cleanup_free_ char *str = NULL;
1131
1132 c->secure_bits = n;
1133 r = secure_bits_to_string_alloc(n, &str);
1134 if (r < 0)
1135 return r;
1136
1137 unit_write_drop_in_private_format(u, mode, name, "SecureBits=%s", str);
1138 }
1139
1140 return 1;
1141 } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) {
1142 uint64_t n;
1143
1144 r = sd_bus_message_read(message, "t", &n);
1145 if (r < 0)
1146 return r;
1147
1148 if (mode != UNIT_CHECK) {
1149 _cleanup_free_ char *str = NULL;
1150
1151 if (streq(name, "CapabilityBoundingSet"))
1152 c->capability_bounding_set = n;
1153 else /* "AmbientCapabilities" */
1154 c->capability_ambient_set = n;
1155
1156 r = capability_set_to_string_alloc(n, &str);
1157 if (r < 0)
1158 return r;
1159
1160 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str);
1161 }
1162
1163 return 1;
1164
1165 } else if (streq(name, "Personality")) {
1166 const char *s;
1167 unsigned long p;
1168
1169 r = sd_bus_message_read(message, "s", &s);
1170 if (r < 0)
1171 return r;
1172
1173 p = personality_from_string(s);
1174 if (p == PERSONALITY_INVALID)
1175 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality");
1176
1177 if (mode != UNIT_CHECK) {
1178 _cleanup_free_ char *str = NULL;
1179
1180 c->personality = p;
1181 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
1182 }
1183
1184 return 1;
1185
1186#ifdef HAVE_SECCOMP
1187
1188 } else if (streq(name, "SystemCallFilter")) {
1189 int whitelist;
1190 _cleanup_strv_free_ char **l;
1191
1192 r = sd_bus_message_enter_container(message, 'r', "bas");
1193 if (r < 0)
1194 return r;
1195
1196 r = sd_bus_message_read(message, "b", &whitelist);
1197 if (r < 0)
1198 return r;
1199
1200 r = sd_bus_message_read_strv(message, &l);
1201 if (r < 0)
1202 return r;
1203
1204 r = sd_bus_message_exit_container(message);
1205 if (r < 0)
1206 return r;
1207
1208 if (mode != UNIT_CHECK) {
1209 _cleanup_free_ char *joined = NULL;
1210
1211 if (strv_length(l) == 0) {
1212 c->syscall_whitelist = false;
1213 c->syscall_filter = set_free(c->syscall_filter);
1214 } else {
1215 char **s;
1216
1217 c->syscall_whitelist = whitelist;
1218
1219 r = set_ensure_allocated(&c->syscall_filter, NULL);
1220 if (r < 0)
1221 return r;
1222
1223 STRV_FOREACH(s, l) {
1224 if (**s == '@') {
1225 const SyscallFilterSet *set;
1226 const char *i;
1227
1228 set = syscall_filter_set_find(*s);
1229 if (!set)
1230 return -EINVAL;
1231
1232 NULSTR_FOREACH(i, set->value) {
1233 int id;
1234
1235 id = seccomp_syscall_resolve_name(i);
1236 if (id == __NR_SCMP_ERROR)
1237 return -EINVAL;
1238
1239 r = set_put(c->address_families, INT_TO_PTR(id + 1));
1240 if (r < 0)
1241 return r;
1242 }
1243
1244 } else {
1245 int id;
1246
1247 id = seccomp_syscall_resolve_name(*s);
1248 if (id == __NR_SCMP_ERROR)
1249 return -EINVAL;
1250
1251 r = set_put(c->address_families, INT_TO_PTR(id + 1));
1252 if (r < 0)
1253 return r;
1254 }
1255 }
1256 }
1257
1258 joined = strv_join(l, " ");
1259 if (!joined)
1260 return -ENOMEM;
1261
1262 unit_write_drop_in_private_format(u, mode, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
1263 }
1264
1265 return 1;
1266
1267 } else if (streq(name, "SystemCallArchitectures")) {
1268 _cleanup_strv_free_ char **l = NULL;
1269
1270 r = sd_bus_message_read_strv(message, &l);
1271 if (r < 0)
1272 return r;
1273
1274 if (mode != UNIT_CHECK) {
1275 _cleanup_free_ char *joined = NULL;
1276
1277 if (strv_length(l) == 0)
1278 c->syscall_archs = set_free(c->syscall_archs);
1279 else {
1280 char **s;
1281
1282 r = set_ensure_allocated(&c->syscall_archs, NULL);
1283 if (r < 0)
1284 return r;
1285
1286 STRV_FOREACH(s, l) {
1287 uint32_t a;
1288
1289 r = seccomp_arch_from_string(*s, &a);
1290 if (r < 0)
1291 return r;
1292
1293 r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
1294 if (r < 0)
1295 return r;
1296 }
1297
1298 }
1299
1300 joined = strv_join(l, " ");
1301 if (!joined)
1302 return -ENOMEM;
1303
1304 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
1305 }
1306
1307 return 1;
1308
1309 } else if (streq(name, "SystemCallErrorNumber")) {
1310 int32_t n;
1311 const char *str;
1312
1313 r = sd_bus_message_read(message, "i", &n);
1314 if (r < 0)
1315 return r;
1316
1317 str = errno_to_name(n);
1318 if (!str)
1319 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber");
1320
1321 if (mode != UNIT_CHECK) {
1322 c->syscall_errno = n;
1323
1324 unit_write_drop_in_private_format(u, mode, name, "SystemCallErrorNumber=%s", str);
1325 }
1326
1327 return 1;
1328
1329 } else if (streq(name, "RestrictAddressFamilies")) {
1330 int whitelist;
1331 _cleanup_strv_free_ char **l;
1332
1333 r = sd_bus_message_enter_container(message, 'r', "bas");
1334 if (r < 0)
1335 return r;
1336
1337 r = sd_bus_message_read(message, "b", &whitelist);
1338 if (r < 0)
1339 return r;
1340
1341 r = sd_bus_message_read_strv(message, &l);
1342 if (r < 0)
1343 return r;
1344
1345 r = sd_bus_message_exit_container(message);
1346 if (r < 0)
1347 return r;
1348
1349 if (mode != UNIT_CHECK) {
1350 _cleanup_free_ char *joined = NULL;
1351
1352 if (strv_length(l) == 0) {
1353 c->address_families_whitelist = false;
1354 c->address_families = set_free(c->address_families);
1355 } else {
1356 char **s;
1357
1358 c->address_families_whitelist = whitelist;
1359
1360 r = set_ensure_allocated(&c->address_families, NULL);
1361 if (r < 0)
1362 return r;
1363
1364 STRV_FOREACH(s, l) {
1365 int af;
1366
1367 af = af_from_name(*s);
1368 if (af <= 0)
1369 return -EINVAL;
1370
1371 r = set_put(c->address_families, INT_TO_PTR(af));
1372 if (r < 0)
1373 return r;
1374 }
1375 }
1376
1377 joined = strv_join(l, " ");
1378 if (!joined)
1379 return -ENOMEM;
1380
1381 unit_write_drop_in_private_format(u, mode, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
1382 }
1383
1384 return 1;
1385#endif
1386
1387 } else if (streq(name, "CPUSchedulingPolicy")) {
1388 int32_t n;
1389
1390 r = sd_bus_message_read(message, "i", &n);
1391 if (r < 0)
1392 return r;
1393
1394 if (!sched_policy_is_valid(n))
1395 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy");
1396
1397 if (mode != UNIT_CHECK) {
1398 _cleanup_free_ char *str = NULL;
1399
1400 c->cpu_sched_policy = n;
1401 r = sched_policy_to_string_alloc(n, &str);
1402 if (r < 0)
1403 return r;
1404
1405 unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPolicy=%s", str);
1406 }
1407
1408 return 1;
1409
1410 } else if (streq(name, "CPUSchedulingPriority")) {
1411 int32_t n;
1412
1413 r = sd_bus_message_read(message, "i", &n);
1414 if (r < 0)
1415 return r;
1416
1417 if (!ioprio_priority_is_valid(n))
1418 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority");
1419
1420 if (mode != UNIT_CHECK) {
1421 c->cpu_sched_priority = n;
1422 unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPriority=%i", n);
1423 }
1424
1425 return 1;
1426
1427 } else if (streq(name, "CPUAffinity")) {
1428 const void *a;
1429 size_t n = 0;
1430
1431 r = sd_bus_message_read_array(message, 'y', &a, &n);
1432 if (r < 0)
1433 return r;
1434
1435 if (mode != UNIT_CHECK) {
1436 if (n == 0) {
1437 c->cpuset = mfree(c->cpuset);
1438 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
1439 } else {
1440 _cleanup_free_ char *str = NULL;
1441 uint8_t *l;
1442 size_t allocated = 0, len = 0, i;
1443
1444 c->cpuset = (cpu_set_t*) memdup(a, sizeof(cpu_set_t) * n);
1445 if (c->cpuset)
1446 return -ENOMEM;
1447
1448 l = (uint8_t*) a;
1449 for (i = 0; i < n; i++) {
1450 _cleanup_free_ char *p = NULL;
1451 size_t add;
1452
1453 r = asprintf(&p, "%hhi", l[i]);
1454 if (r < 0)
1455 return -ENOMEM;
1456
1457 add = strlen(p);
1458
1459 if (GREEDY_REALLOC(str, allocated, len + add + 2))
1460 return -ENOMEM;
1461
1462 strcpy(mempcpy(str + len, p, add), " ");
1463 len += add + 1;
1464 }
1465
1466 if (len != 0)
1467 str[len - 1] = '\0';
1468
1469 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str);
1470 }
1471 }
1472
de53c417 1473 return 1;
c7040b5d 1474 } else if (streq(name, "Nice")) {
8d1dd6ab 1475 int32_t n;
c7040b5d
LP
1476
1477 r = sd_bus_message_read(message, "i", &n);
1478 if (r < 0)
1479 return r;
1480
41bf0590 1481 if (!nice_is_valid(n))
c7040b5d
LP
1482 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
1483
1484 if (mode != UNIT_CHECK) {
1485 c->nice = n;
b27b4b51 1486 unit_write_drop_in_private_format(u, mode, name, "Nice=%i", n);
c7040b5d
LP
1487 }
1488
1489 return 1;
1490
7f452159
LP
1491 } else if (streq(name, "IOSchedulingClass")) {
1492 int32_t q;
1493
1494 r = sd_bus_message_read(message, "i", &q);
1495 if (r < 0)
1496 return r;
1497
1498 if (!ioprio_class_is_valid(q))
1499 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
1500
1501 if (mode != UNIT_CHECK) {
1502 _cleanup_free_ char *s = NULL;
1503
1504 r = ioprio_class_to_string_alloc(q, &s);
1505 if (r < 0)
1506 return r;
1507
1508 c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
1509 c->ioprio_set = true;
1510
1511 unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
1512 }
1513
1514 return 1;
1515
1516 } else if (streq(name, "IOSchedulingPriority")) {
1517 int32_t p;
1518
1519 r = sd_bus_message_read(message, "i", &p);
1520 if (r < 0)
1521 return r;
1522
1523 if (!ioprio_priority_is_valid(p))
1524 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
1525
1526 if (mode != UNIT_CHECK) {
1527 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
1528 c->ioprio_set = true;
1529
1530 unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
1531 }
1532
1533 return 1;
1534
915e6d16 1535 } else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
602b8355 1536 const char *s;
9b15b784 1537
602b8355 1538 r = sd_bus_message_read(message, "s", &s);
9b15b784
LP
1539 if (r < 0)
1540 return r;
1541
602b8355
NC
1542 if (!path_is_absolute(s))
1543 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
9b15b784
LP
1544
1545 if (mode != UNIT_CHECK) {
5f5d8eab
LP
1546 if (streq(name, "TTYPath"))
1547 r = free_and_strdup(&c->tty_path, s);
915e6d16
LP
1548 else if (streq(name, "RootImage"))
1549 r = free_and_strdup(&c->root_image, s);
5f5d8eab
LP
1550 else {
1551 assert(streq(name, "RootDirectory"));
1552 r = free_and_strdup(&c->root_directory, s);
602b8355 1553 }
5f5d8eab
LP
1554 if (r < 0)
1555 return r;
9b15b784 1556
b27b4b51 1557 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
9b15b784
LP
1558 }
1559
1560 return 1;
1561
5f5d8eab
LP
1562 } else if (streq(name, "WorkingDirectory")) {
1563 const char *s;
1564 bool missing_ok;
1565
1566 r = sd_bus_message_read(message, "s", &s);
1567 if (r < 0)
1568 return r;
1569
1570 if (s[0] == '-') {
1571 missing_ok = true;
1572 s++;
1573 } else
1574 missing_ok = false;
1575
1576 if (!streq(s, "~") && !path_is_absolute(s))
1577 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
1578
1579 if (mode != UNIT_CHECK) {
1580 if (streq(s, "~")) {
1581 c->working_directory = mfree(c->working_directory);
1582 c->working_directory_home = true;
1583 } else {
1584 r = free_and_strdup(&c->working_directory, s);
1585 if (r < 0)
1586 return r;
1587
1588 c->working_directory_home = false;
1589 }
1590
1591 c->working_directory_missing_ok = missing_ok;
b27b4b51 1592 unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
5f5d8eab
LP
1593 }
1594
1595 return 1;
1596
9b15b784
LP
1597 } else if (streq(name, "StandardInput")) {
1598 const char *s;
1599 ExecInput p;
1600
1601 r = sd_bus_message_read(message, "s", &s);
1602 if (r < 0)
1603 return r;
1604
1605 p = exec_input_from_string(s);
1606 if (p < 0)
1607 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
1608
1609 if (mode != UNIT_CHECK) {
1610 c->std_input = p;
1611
b27b4b51 1612 unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s", exec_input_to_string(p));
9b15b784
LP
1613 }
1614
1615 return 1;
1616
9b15b784
LP
1617 } else if (streq(name, "StandardOutput")) {
1618 const char *s;
1619 ExecOutput p;
1620
1621 r = sd_bus_message_read(message, "s", &s);
1622 if (r < 0)
1623 return r;
1624
1625 p = exec_output_from_string(s);
1626 if (p < 0)
1627 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
1628
1629 if (mode != UNIT_CHECK) {
1630 c->std_output = p;
1631
b27b4b51 1632 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s", exec_output_to_string(p));
9b15b784
LP
1633 }
1634
1635 return 1;
1636
1637 } else if (streq(name, "StandardError")) {
1638 const char *s;
1639 ExecOutput p;
1640
1641 r = sd_bus_message_read(message, "s", &s);
1642 if (r < 0)
1643 return r;
1644
1645 p = exec_output_from_string(s);
1646 if (p < 0)
1647 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
1648
1649 if (mode != UNIT_CHECK) {
1650 c->std_error = p;
1651
b27b4b51 1652 unit_write_drop_in_private_format(u, mode, name, "StandardError=%s", exec_output_to_string(p));
9b15b784
LP
1653 }
1654
1655 return 1;
1656
52c239d7
LB
1657 } else if (STR_IN_SET(name,
1658 "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
1659 const char *s;
1660
1661 r = sd_bus_message_read(message, "s", &s);
1662 if (r < 0)
1663 return r;
1664
1665 if (!fdname_is_valid(s))
1666 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
1667
1668 if (mode != UNIT_CHECK) {
1669 if (streq(name, "StandardInputFileDescriptorName")) {
1670 c->std_input = EXEC_INPUT_NAMED_FD;
1671 r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], s);
1672 if (r < 0)
1673 return r;
1674 unit_write_drop_in_private_format(u, mode, name, "StandardInput=fd:%s", s);
1675 } else if (streq(name, "StandardOutputFileDescriptorName")) {
1676 c->std_output = EXEC_OUTPUT_NAMED_FD;
1677 r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], s);
1678 if (r < 0)
1679 return r;
1680 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=fd:%s", s);
1681 } else if (streq(name, "StandardErrorFileDescriptorName")) {
1682 c->std_error = EXEC_OUTPUT_NAMED_FD;
1683 r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s);
1684 if (r < 0)
1685 return r;
1686 unit_write_drop_in_private_format(u, mode, name, "StandardError=fd:%s", s);
1687 }
1688 }
1689
1690 return 1;
1691
b9c50073 1692 } else if (STR_IN_SET(name,
cffaed83 1693 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
d251207d 1694 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
29206d46 1695 "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
59eeb84b 1696 "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
cffaed83
YW
1697 "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
1698 "CPUSchedulingResetOnFork", "NonBlocking")) {
506711fd
LP
1699 int b;
1700
1701 r = sd_bus_message_read(message, "b", &b);
1702 if (r < 0)
1703 return r;
1704
1705 if (mode != UNIT_CHECK) {
b9c50073
GP
1706 if (streq(name, "IgnoreSIGPIPE"))
1707 c->ignore_sigpipe = b;
1708 else if (streq(name, "TTYVHangup"))
1709 c->tty_vhangup = b;
1710 else if (streq(name, "TTYReset"))
1711 c->tty_reset = b;
cffaed83
YW
1712 else if (streq(name, "TTYVTDisallocate"))
1713 c->tty_vt_disallocate = b;
b9c50073
GP
1714 else if (streq(name, "PrivateTmp"))
1715 c->private_tmp = b;
1716 else if (streq(name, "PrivateDevices"))
1717 c->private_devices = b;
1718 else if (streq(name, "PrivateNetwork"))
1719 c->private_network = b;
d251207d
LP
1720 else if (streq(name, "PrivateUsers"))
1721 c->private_users = b;
b9c50073
GP
1722 else if (streq(name, "NoNewPrivileges"))
1723 c->no_new_privileges = b;
047d9933
EV
1724 else if (streq(name, "SyslogLevelPrefix"))
1725 c->syslog_level_prefix = b;
f3e43635
TM
1726 else if (streq(name, "MemoryDenyWriteExecute"))
1727 c->memory_deny_write_execute = b;
f4170c67
LP
1728 else if (streq(name, "RestrictRealtime"))
1729 c->restrict_realtime = b;
29206d46
LP
1730 else if (streq(name, "DynamicUser"))
1731 c->dynamic_user = b;
00d9ef85
LP
1732 else if (streq(name, "RemoveIPC"))
1733 c->remove_ipc = b;
59eeb84b
LP
1734 else if (streq(name, "ProtectKernelTunables"))
1735 c->protect_kernel_tunables = b;
502d704e
DH
1736 else if (streq(name, "ProtectKernelModules"))
1737 c->protect_kernel_modules = b;
59eeb84b
LP
1738 else if (streq(name, "ProtectControlGroups"))
1739 c->protect_control_groups = b;
5d997827
LP
1740 else if (streq(name, "MountAPIVFS"))
1741 c->mount_apivfs = b;
cffaed83
YW
1742 else if (streq(name, "CPUSchedulingResetOnFork"))
1743 c->cpu_sched_reset_on_fork = b;
1744 else if (streq(name, "NonBlocking"))
1745 c->non_blocking = b;
b9c50073 1746
b27b4b51 1747 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, yes_no(b));
506711fd
LP
1748 }
1749
1750 return 1;
1751
1752 } else if (streq(name, "UtmpIdentifier")) {
1753 const char *id;
1754
1755 r = sd_bus_message_read(message, "s", &id);
1756 if (r < 0)
1757 return r;
1758
1759 if (mode != UNIT_CHECK) {
76736280
LP
1760 if (isempty(id))
1761 c->utmp_id = mfree(c->utmp_id);
1762 else if (free_and_strdup(&c->utmp_id, id) < 0)
1763 return -ENOMEM;
506711fd 1764
b27b4b51 1765 unit_write_drop_in_private_format(u, mode, name, "UtmpIdentifier=%s", strempty(id));
506711fd
LP
1766 }
1767
1768 return 1;
1769
1770 } else if (streq(name, "UtmpMode")) {
1771 const char *s;
1772 ExecUtmpMode m;
1773
1774 r = sd_bus_message_read(message, "s", &s);
1775 if (r < 0)
1776 return r;
1777
1778 m = exec_utmp_mode_from_string(s);
1779 if (m < 0)
1780 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
1781
1782 if (mode != UNIT_CHECK) {
1783 c->utmp_mode = m;
1784
b27b4b51 1785 unit_write_drop_in_private_format(u, mode, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
506711fd
LP
1786 }
1787
1788 return 1;
1789
1790 } else if (streq(name, "PAMName")) {
1791 const char *n;
1792
1793 r = sd_bus_message_read(message, "s", &n);
1794 if (r < 0)
1795 return r;
1796
1797 if (mode != UNIT_CHECK) {
76736280
LP
1798 if (isempty(n))
1799 c->pam_name = mfree(c->pam_name);
1800 else if (free_and_strdup(&c->pam_name, n) < 0)
1801 return -ENOMEM;
506711fd 1802
b27b4b51 1803 unit_write_drop_in_private_format(u, mode, name, "PAMName=%s", strempty(n));
506711fd
LP
1804 }
1805
1806 return 1;
1807
c7040b5d
LP
1808 } else if (streq(name, "Environment")) {
1809
f900f582 1810 _cleanup_strv_free_ char **l = NULL, **q = NULL;
c7040b5d
LP
1811
1812 r = sd_bus_message_read_strv(message, &l);
1813 if (r < 0)
1814 return r;
1815
1816 if (!strv_env_is_valid(l))
1817 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
1818
f900f582
ZJS
1819 r = unit_full_printf_strv(u, l, &q);
1820 if (r < 0)
1821 return r;
c7040b5d 1822
f900f582
ZJS
1823 if (mode != UNIT_CHECK) {
1824 if (strv_length(q) == 0) {
e9876fc9 1825 c->environment = strv_free(c->environment);
b27b4b51 1826 unit_write_drop_in_private_format(u, mode, name, "Environment=");
e9876fc9 1827 } else {
f900f582
ZJS
1828 _cleanup_free_ char *joined = NULL;
1829 char **e;
1830
1831 e = strv_env_merge(2, c->environment, q);
e9876fc9
EV
1832 if (!e)
1833 return -ENOMEM;
c7040b5d 1834
e9876fc9
EV
1835 strv_free(c->environment);
1836 c->environment = e;
c7040b5d 1837
f900f582
ZJS
1838 /* We write just the new settings out to file, with unresolved specifiers */
1839 joined = strv_join_quoted(q);
e9876fc9
EV
1840 if (!joined)
1841 return -ENOMEM;
1842
b27b4b51 1843 unit_write_drop_in_private_format(u, mode, name, "Environment=%s", joined);
e9876fc9 1844 }
c7040b5d
LP
1845 }
1846
d584f638
LP
1847 return 1;
1848
f1db3327
EV
1849 } else if (streq(name, "TimerSlackNSec")) {
1850
1851 nsec_t n;
1852
1853 r = sd_bus_message_read(message, "t", &n);
1854 if (r < 0)
1855 return r;
1856
1857 if (mode != UNIT_CHECK) {
1858 c->timer_slack_nsec = n;
b27b4b51 1859 unit_write_drop_in_private_format(u, mode, name, "TimerSlackNSec=" NSEC_FMT, n);
f1db3327
EV
1860 }
1861
1862 return 1;
1863
6b862936
EV
1864 } else if (streq(name, "OOMScoreAdjust")) {
1865 int oa;
1866
1867 r = sd_bus_message_read(message, "i", &oa);
1868 if (r < 0)
1869 return r;
1870
1871 if (!oom_score_adjust_is_valid(oa))
1872 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
1873
1874 if (mode != UNIT_CHECK) {
1875 c->oom_score_adjust = oa;
1876 c->oom_score_adjust_set = true;
b27b4b51 1877 unit_write_drop_in_private_format(u, mode, name, "OOMScoreAdjust=%i", oa);
6b862936
EV
1878 }
1879
1880 return 1;
1881
ceb728cf
NC
1882 } else if (streq(name, "EnvironmentFiles")) {
1883
1884 _cleanup_free_ char *joined = NULL;
1885 _cleanup_fclose_ FILE *f = NULL;
9b531f04 1886 _cleanup_strv_free_ char **l = NULL;
ceb728cf 1887 size_t size = 0;
2229f656 1888 char **i;
ceb728cf
NC
1889
1890 r = sd_bus_message_enter_container(message, 'a', "(sb)");
1891 if (r < 0)
1892 return r;
1893
1894 f = open_memstream(&joined, &size);
1895 if (!f)
1896 return -ENOMEM;
1897
2229f656 1898 STRV_FOREACH(i, c->environment_files)
b27b4b51 1899 fprintf(f, "EnvironmentFile=%s", *i);
ceb728cf
NC
1900
1901 while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
1902 const char *path;
1903 int b;
1904
ceb728cf
NC
1905 r = sd_bus_message_read(message, "sb", &path, &b);
1906 if (r < 0)
1907 return r;
1908
1909 r = sd_bus_message_exit_container(message);
1910 if (r < 0)
1911 return r;
1912
d2d6c096
LP
1913 if (!path_is_absolute(path))
1914 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
ceb728cf
NC
1915
1916 if (mode != UNIT_CHECK) {
ceb728cf
NC
1917 char *buf = NULL;
1918
605405c6 1919 buf = strjoin(b ? "-" : "", path);
2229f656 1920 if (!buf)
ceb728cf
NC
1921 return -ENOMEM;
1922
b27b4b51 1923 fprintf(f, "EnvironmentFile=%s", buf);
ceb728cf 1924
2229f656 1925 r = strv_consume(&l, buf);
ceb728cf
NC
1926 if (r < 0)
1927 return r;
1928 }
1929 }
1930 if (r < 0)
1931 return r;
1932
b0830e21
LP
1933 r = sd_bus_message_exit_container(message);
1934 if (r < 0)
1935 return r;
1936
2229f656
LP
1937 r = fflush_and_check(f);
1938 if (r < 0)
1939 return r;
ceb728cf 1940
2229f656
LP
1941 if (mode != UNIT_CHECK) {
1942 if (strv_isempty(l)) {
1943 c->environment_files = strv_free(c->environment_files);
b27b4b51 1944 unit_write_drop_in_private(u, mode, name, "EnvironmentFile=");
2229f656
LP
1945 } else {
1946 r = strv_extend_strv(&c->environment_files, l, true);
1947 if (r < 0)
1948 return r;
1949
ceb728cf 1950 unit_write_drop_in_private(u, mode, name, joined);
2229f656
LP
1951 }
1952 }
ceb728cf 1953
ceb728cf
NC
1954 return 1;
1955
b4c14404
FB
1956 } else if (streq(name, "PassEnvironment")) {
1957
1958 _cleanup_strv_free_ char **l = NULL;
1959
1960 r = sd_bus_message_read_strv(message, &l);
1961 if (r < 0)
1962 return r;
1963
1964 if (!strv_env_name_is_valid(l))
1965 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment block.");
1966
1967 if (mode != UNIT_CHECK) {
1968 if (strv_isempty(l)) {
1969 c->pass_environment = strv_free(c->pass_environment);
b27b4b51 1970 unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=");
b4c14404
FB
1971 } else {
1972 _cleanup_free_ char *joined = NULL;
1973
1974 r = strv_extend_strv(&c->pass_environment, l, true);
1975 if (r < 0)
1976 return r;
1977
1978 joined = strv_join_quoted(c->pass_environment);
1979 if (!joined)
1980 return -ENOMEM;
1981
b27b4b51 1982 unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=%s", joined);
b4c14404
FB
1983 }
1984 }
1985
1986 return 1;
1987
2a624c36
AP
1988 } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
1989 "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
08596068
EV
1990 _cleanup_strv_free_ char **l = NULL;
1991 char ***dirs;
1992 char **p;
1993
1994 r = sd_bus_message_read_strv(message, &l);
1995 if (r < 0)
1996 return r;
1997
1998 STRV_FOREACH(p, l) {
20b7a007
LP
1999 const char *i = *p;
2000 size_t offset;
2001
2002 if (!utf8_is_valid(i))
08596068
EV
2003 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
2004
20b7a007
LP
2005 offset = i[0] == '-';
2006 offset += i[offset] == '+';
2007 if (!path_is_absolute(i + offset))
08596068
EV
2008 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
2009 }
2010
2011 if (mode != UNIT_CHECK) {
2012 _cleanup_free_ char *joined = NULL;
2013
c4b41707
AP
2014 if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
2015 dirs = &c->read_write_paths;
2016 else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
2017 dirs = &c->read_only_paths;
2018 else /* "InaccessiblePaths" */
2019 dirs = &c->inaccessible_paths;
08596068
EV
2020
2021 if (strv_length(l) == 0) {
2022 *dirs = strv_free(*dirs);
b27b4b51 2023 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
08596068
EV
2024 } else {
2025 r = strv_extend_strv(dirs, l, true);
08596068
EV
2026 if (r < 0)
2027 return -ENOMEM;
2028
2029 joined = strv_join_quoted(*dirs);
2030 if (!joined)
2031 return -ENOMEM;
2032
b27b4b51 2033 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
08596068
EV
2034 }
2035
2036 }
2037
2038 return 1;
2039
5664e6cf
EV
2040 } else if (streq(name, "ProtectSystem")) {
2041 const char *s;
2042 ProtectSystem ps;
2043
2044 r = sd_bus_message_read(message, "s", &s);
2045 if (r < 0)
2046 return r;
2047
2048 r = parse_boolean(s);
2049 if (r > 0)
2050 ps = PROTECT_SYSTEM_YES;
2051 else if (r == 0)
2052 ps = PROTECT_SYSTEM_NO;
2053 else {
2054 ps = protect_system_from_string(s);
2055 if (ps < 0)
2056 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value");
2057 }
2058
2059 if (mode != UNIT_CHECK) {
2060 c->protect_system = ps;
b27b4b51 2061 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
5664e6cf
EV
2062 }
2063
2064 return 1;
2065
eff58074
EV
2066 } else if (streq(name, "ProtectHome")) {
2067 const char *s;
2068 ProtectHome ph;
2069
2070 r = sd_bus_message_read(message, "s", &s);
2071 if (r < 0)
2072 return r;
2073
2074 r = parse_boolean(s);
2075 if (r > 0)
2076 ph = PROTECT_HOME_YES;
2077 else if (r == 0)
2078 ph = PROTECT_HOME_NO;
2079 else {
2080 ph = protect_home_from_string(s);
2081 if (ph < 0)
2082 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value");
2083 }
2084
2085 if (mode != UNIT_CHECK) {
2086 c->protect_home = ph;
b27b4b51 2087 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
eff58074
EV
2088 }
2089
2090 return 1;
2091
53f47dfc
YW
2092 } else if (streq(name, "RuntimeDirectoryPreserve")) {
2093 const char *s;
2094 ExecPreserveMode m;
2095
2096 r = sd_bus_message_read(message, "s", &s);
2097 if (r < 0)
2098 return r;
2099
2100 m = exec_preserve_mode_from_string(s);
2101 if (m < 0)
2102 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode");
2103
2104 if (mode != UNIT_CHECK) {
2105 c->runtime_directory_preserve_mode = m;
2106
2107 unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
2108 }
2109
2110 return 1;
2111
cffaed83 2112 } else if (STR_IN_SET(name, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) {
53f47dfc
YW
2113 mode_t m;
2114
2115 r = sd_bus_message_read(message, "u", &m);
2116 if (r < 0)
2117 return r;
2118
2119 if (mode != UNIT_CHECK) {
3536f49e 2120 ExecDirectoryType i;
53f47dfc 2121
cffaed83
YW
2122 if (streq(name, "UMask"))
2123 c->umask = m;
2124 else
2125 for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
2126 if (startswith(name, exec_directory_type_to_string(i))) {
2127 c->directories[i].mode = m;
2128 break;
2129 }
3536f49e
YW
2130
2131 unit_write_drop_in_private_format(u, mode, name, "%s=%040o", name, m);
53f47dfc
YW
2132 }
2133
2134 return 1;
2135
3536f49e 2136 } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
fa21b5e3
EV
2137 _cleanup_strv_free_ char **l = NULL;
2138 char **p;
2139
2140 r = sd_bus_message_read_strv(message, &l);
2141 if (r < 0)
2142 return r;
2143
2144 STRV_FOREACH(p, l) {
2145 if (!filename_is_valid(*p))
3536f49e 2146 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s is not valid %s", name, *p);
fa21b5e3
EV
2147 }
2148
2149 if (mode != UNIT_CHECK) {
2150 _cleanup_free_ char *joined = NULL;
3536f49e
YW
2151 char ***dirs = NULL;
2152 ExecDirectoryType i;
2153
2154 for (i = 0; i < _EXEC_DIRECTORY_MAX; i++)
2155 if (streq(name, exec_directory_type_to_string(i))) {
2156 dirs = &c->directories[i].paths;
2157 break;
2158 }
2159
2160 assert(dirs);
fa21b5e3
EV
2161
2162 if (strv_isempty(l)) {
3536f49e 2163 *dirs = strv_free(*dirs);
b27b4b51 2164 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
fa21b5e3 2165 } else {
3536f49e 2166 r = strv_extend_strv(dirs, l, true);
fa21b5e3
EV
2167
2168 if (r < 0)
2169 return -ENOMEM;
2170
3536f49e 2171 joined = strv_join_quoted(*dirs);
fa21b5e3
EV
2172 if (!joined)
2173 return -ENOMEM;
2174
b27b4b51 2175 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
fa21b5e3
EV
2176 }
2177 }
2178
2179 return 1;
2180
186ad4b1
JB
2181 } else if (streq(name, "SELinuxContext")) {
2182 const char *s;
186ad4b1
JB
2183 r = sd_bus_message_read(message, "s", &s);
2184 if (r < 0)
2185 return r;
2186
2187 if (mode != UNIT_CHECK) {
4e282d11
JB
2188 if (isempty(s))
2189 c->selinux_context = mfree(c->selinux_context);
2190 else if (free_and_strdup(&c->selinux_context, s) < 0)
2191 return -ENOMEM;
186ad4b1 2192
b27b4b51 2193 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, strempty(s));
186ad4b1
JB
2194 }
2195
2196 return 1;
cffaed83
YW
2197
2198 } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
2199 int ignore;
2200 const char *s;
2201
2202 r = sd_bus_message_enter_container(message, 'r', "bs");
2203 if (r < 0)
2204 return r;
2205
2206 r = sd_bus_message_read(message, "bs", &ignore, &s);
2207 if (r < 0)
2208 return r;
2209
2210 if (mode != UNIT_CHECK) {
2211 char **p;
2212 bool *b;
2213
2214 if (streq(name, "AppArmorProfile")) {
2215 p = &c->apparmor_profile;
2216 b = &c->apparmor_profile_ignore;
2217 } else { /* "SmackProcessLabel" */
2218 p = &c->smack_process_label;
2219 b = &c->smack_process_label_ignore;
2220 }
2221
2222 if (isempty(s)) {
2223 *p = mfree(*p);
2224 *b = false;
2225 } else {
2226 if (free_and_strdup(p, s) < 0)
2227 return -ENOMEM;
2228 *b = ignore;
2229 }
2230
2231 unit_write_drop_in_private_format(u, mode, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
2232 }
2233
2234 return 1;
2235
add00535
LP
2236 } else if (streq(name, "RestrictNamespaces")) {
2237 uint64_t flags;
186ad4b1 2238
add00535
LP
2239 r = sd_bus_message_read(message, "t", &flags);
2240 if (r < 0)
2241 return r;
2242 if ((flags & NAMESPACE_FLAGS_ALL) != flags)
2243 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
2244
2245 if (mode != UNIT_CHECK) {
2246 _cleanup_free_ char *s = NULL;
2247
2248 r = namespace_flag_to_string_many(flags, &s);
2249 if (r < 0)
2250 return r;
2251
2252 c->restrict_namespaces = flags;
2253 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
2254 }
2255
2256 return 1;
83555251
LP
2257 } else if (streq(name, "MountFlags")) {
2258 uint64_t flags;
2259
2260 r = sd_bus_message_read(message, "t", &flags);
2261 if (r < 0)
2262 return r;
2263 if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
2264 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
cab2aca3 2265
83555251
LP
2266 if (mode != UNIT_CHECK) {
2267 c->mount_flags = flags;
2268
c7383828 2269 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, mount_propagation_flags_to_string(flags));
83555251
LP
2270 }
2271
d2d6c096
LP
2272 return 1;
2273 } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
2274 unsigned empty = true;
2275
2276 r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
2277 if (r < 0)
2278 return r;
2279
2280 while ((r = sd_bus_message_enter_container(message, 'r', "ssbt")) > 0) {
2281 const char *source, *destination;
2282 int ignore_enoent;
2283 uint64_t mount_flags;
2284
2285 r = sd_bus_message_read(message, "ssbt", &source, &destination, &ignore_enoent, &mount_flags);
2286 if (r < 0)
2287 return r;
2288
2289 r = sd_bus_message_exit_container(message);
2290 if (r < 0)
2291 return r;
2292
2293 if (!path_is_absolute(source))
2294 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
2295 if (!path_is_absolute(destination))
91d910e3 2296 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
d2d6c096
LP
2297 if (!IN_SET(mount_flags, 0, MS_REC))
2298 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
2299
2300 if (mode != UNIT_CHECK) {
2301 r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
2302 &(BindMount) {
2303 .source = strdup(source),
2304 .destination = strdup(destination),
2305 .read_only = !!strstr(name, "ReadOnly"),
2306 .recursive = !!(mount_flags & MS_REC),
2307 .ignore_enoent = ignore_enoent,
2308 });
2309 if (r < 0)
2310 return r;
2311
2312 unit_write_drop_in_private_format(
2313 u, mode, name,
2314 "%s=%s%s:%s:%s",
2315 name,
2316 ignore_enoent ? "-" : "",
2317 source,
2318 destination,
2319 (mount_flags & MS_REC) ? "rbind" : "norbind");
2320 }
2321
2322 empty = false;
2323 }
2324 if (r < 0)
2325 return r;
2326
2327 r = sd_bus_message_exit_container(message);
2328 if (r < 0)
2329 return r;
2330
2331 if (empty) {
2332 bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
2333 c->bind_mounts = NULL;
2334 c->n_bind_mounts = 0;
2335 }
2336
83555251
LP
2337 return 1;
2338 }
d2d6c096 2339
cab2aca3
LP
2340 ri = rlimit_from_string(name);
2341 if (ri < 0) {
2342 soft = endswith(name, "Soft");
2343 if (soft) {
2344 const char *n;
2345
2346 n = strndupa(name, soft - name);
2347 ri = rlimit_from_string(n);
2348 if (ri >= 0)
2349 name = n;
2350
2351 }
2352 }
2353
2354 if (ri >= 0) {
d584f638
LP
2355 uint64_t rl;
2356 rlim_t x;
2357
2358 r = sd_bus_message_read(message, "t", &rl);
2359 if (r < 0)
2360 return r;
2361
2362 if (rl == (uint64_t) -1)
2363 x = RLIM_INFINITY;
2364 else {
2365 x = (rlim_t) rl;
2366
2367 if ((uint64_t) x != rl)
2368 return -ERANGE;
2369 }
2370
2371 if (mode != UNIT_CHECK) {
cab2aca3
LP
2372 _cleanup_free_ char *f = NULL;
2373 struct rlimit nl;
2374
2375 if (c->rlimit[ri]) {
2376 nl = *c->rlimit[ri];
2377
2378 if (soft)
2379 nl.rlim_cur = x;
2380 else
2381 nl.rlim_max = x;
2382 } else
2383 /* When the resource limit is not initialized yet, then assign the value to both fields */
2384 nl = (struct rlimit) {
2385 .rlim_cur = x,
2386 .rlim_max = x,
2387 };
2388
2389 r = rlimit_format(&nl, &f);
2390 if (r < 0)
2391 return r;
d584f638 2392
cab2aca3
LP
2393 if (c->rlimit[ri])
2394 *c->rlimit[ri] = nl;
2395 else {
2396 c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
2397 if (!c->rlimit[ri])
d584f638
LP
2398 return -ENOMEM;
2399 }
2400
b27b4b51 2401 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, f);
d584f638
LP
2402 }
2403
c7040b5d
LP
2404 return 1;
2405 }
2406
2407 return 0;
2408}