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