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