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