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