]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-execute.c
Merge pull request #6349 from poettering/mkosi-builddir
[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),
e66cf1a3 854 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
53f47dfc 855 SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
e66cf1a3 856 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
f3e43635 857 SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
f4170c67 858 SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
6a8c2d59 859 SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
d2d6c096
LP
860 SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
861 SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
5d997827 862 SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
7f452159
LP
863
864 /* Obsolete/redundant properties: */
865 SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
866 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
867 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
868 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
869 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
870
718db961
LP
871 SD_BUS_VTABLE_END
872};
82c121a4 873
4d4c80d0
LP
874static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
875 int r;
876
877 assert(reply);
878 assert(c);
879
880 if (!c->path)
881 return 0;
882
883 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
884 if (r < 0)
885 return r;
886
887 r = sd_bus_message_append(reply, "s", c->path);
888 if (r < 0)
889 return r;
890
891 r = sd_bus_message_append_strv(reply, c->argv);
892 if (r < 0)
893 return r;
894
895 r = sd_bus_message_append(reply, "bttttuii",
896 c->ignore,
897 c->exec_status.start_timestamp.realtime,
898 c->exec_status.start_timestamp.monotonic,
899 c->exec_status.exit_timestamp.realtime,
900 c->exec_status.exit_timestamp.monotonic,
901 (uint32_t) c->exec_status.pid,
902 (int32_t) c->exec_status.code,
903 (int32_t) c->exec_status.status);
904 if (r < 0)
905 return r;
906
907 return sd_bus_message_close_container(reply);
908}
909
718db961
LP
910int bus_property_get_exec_command(
911 sd_bus *bus,
912 const char *path,
913 const char *interface,
914 const char *property,
915 sd_bus_message *reply,
ebcf1f97
LP
916 void *userdata,
917 sd_bus_error *ret_error) {
fe68089d 918
4d4c80d0 919 ExecCommand *c = (ExecCommand*) userdata;
718db961 920 int r;
fe68089d 921
718db961
LP
922 assert(bus);
923 assert(reply);
fe68089d 924
718db961
LP
925 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
926 if (r < 0)
927 return r;
fe68089d 928
4d4c80d0
LP
929 r = append_exec_command(reply, c);
930 if (r < 0)
931 return r;
fe68089d 932
4d4c80d0
LP
933 return sd_bus_message_close_container(reply);
934}
718db961 935
4d4c80d0
LP
936int bus_property_get_exec_command_list(
937 sd_bus *bus,
938 const char *path,
939 const char *interface,
940 const char *property,
941 sd_bus_message *reply,
942 void *userdata,
943 sd_bus_error *ret_error) {
718db961 944
4d4c80d0
LP
945 ExecCommand *c = *(ExecCommand**) userdata;
946 int r;
718db961 947
4d4c80d0
LP
948 assert(bus);
949 assert(reply);
950
951 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
952 if (r < 0)
953 return r;
718db961 954
4d4c80d0
LP
955 LIST_FOREACH(command, c, c) {
956 r = append_exec_command(reply, c);
718db961
LP
957 if (r < 0)
958 return r;
fe68089d
LP
959 }
960
718db961 961 return sd_bus_message_close_container(reply);
8351ceae 962}
c7040b5d
LP
963
964int bus_exec_context_set_transient_property(
965 Unit *u,
966 ExecContext *c,
967 const char *name,
968 sd_bus_message *message,
969 UnitSetPropertiesMode mode,
970 sd_bus_error *error) {
971
cab2aca3
LP
972 const char *soft = NULL;
973 int r, ri;
c7040b5d
LP
974
975 assert(u);
976 assert(c);
977 assert(name);
978 assert(message);
979
980 if (streq(name, "User")) {
981 const char *uu;
982
983 r = sd_bus_message_read(message, "s", &uu);
984 if (r < 0)
985 return r;
986
6f3e7985
LP
987 if (!isempty(uu) && !valid_user_group_name_or_id(uu))
988 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu);
989
c7040b5d 990 if (mode != UNIT_CHECK) {
76736280
LP
991
992 if (isempty(uu))
993 c->user = mfree(c->user);
994 else if (free_and_strdup(&c->user, uu) < 0)
995 return -ENOMEM;
c7040b5d 996
b27b4b51 997 unit_write_drop_in_private_format(u, mode, name, "User=%s", uu);
c7040b5d
LP
998 }
999
1000 return 1;
1001
1002 } else if (streq(name, "Group")) {
1003 const char *gg;
1004
1005 r = sd_bus_message_read(message, "s", &gg);
1006 if (r < 0)
1007 return r;
1008
6f3e7985
LP
1009 if (!isempty(gg) && !valid_user_group_name_or_id(gg))
1010 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg);
1011
c7040b5d 1012 if (mode != UNIT_CHECK) {
76736280
LP
1013
1014 if (isempty(gg))
1015 c->group = mfree(c->group);
1016 else if (free_and_strdup(&c->group, gg) < 0)
1017 return -ENOMEM;
c7040b5d 1018
b27b4b51 1019 unit_write_drop_in_private_format(u, mode, name, "Group=%s", gg);
c7040b5d
LP
1020 }
1021
1022 return 1;
de53c417
EV
1023 } else if (streq(name, "SyslogIdentifier")) {
1024 const char *id;
c7040b5d 1025
de53c417
EV
1026 r = sd_bus_message_read(message, "s", &id);
1027 if (r < 0)
1028 return r;
1029
1030 if (mode != UNIT_CHECK) {
76736280
LP
1031
1032 if (isempty(id))
1033 c->syslog_identifier = mfree(c->syslog_identifier);
1034 else if (free_and_strdup(&c->syslog_identifier, id) < 0)
1035 return -ENOMEM;
de53c417 1036
b27b4b51 1037 unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s", id);
de53c417
EV
1038 }
1039
a8a13575
EV
1040 return 1;
1041 } else if (streq(name, "SyslogLevel")) {
8d1dd6ab 1042 int32_t level;
a8a13575
EV
1043
1044 r = sd_bus_message_read(message, "i", &level);
1045 if (r < 0)
1046 return r;
1047
e0d6e0fa
EV
1048 if (!log_level_is_valid(level))
1049 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
1050
a8a13575
EV
1051 if (mode != UNIT_CHECK) {
1052 c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
b27b4b51 1053 unit_write_drop_in_private_format(u, mode, name, "SyslogLevel=%i", level);
a8a13575
EV
1054 }
1055
460ed929
EV
1056 return 1;
1057 } else if (streq(name, "SyslogFacility")) {
8d1dd6ab 1058 int32_t facility;
460ed929
EV
1059
1060 r = sd_bus_message_read(message, "i", &facility);
1061 if (r < 0)
1062 return r;
1063
e0d6e0fa
EV
1064 if (!log_facility_unshifted_is_valid(facility))
1065 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
1066
460ed929
EV
1067 if (mode != UNIT_CHECK) {
1068 c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
b27b4b51 1069 unit_write_drop_in_private_format(u, mode, name, "SyslogFacility=%i", facility);
460ed929
EV
1070 }
1071
de53c417 1072 return 1;
c7040b5d 1073 } else if (streq(name, "Nice")) {
8d1dd6ab 1074 int32_t n;
c7040b5d
LP
1075
1076 r = sd_bus_message_read(message, "i", &n);
1077 if (r < 0)
1078 return r;
1079
41bf0590 1080 if (!nice_is_valid(n))
c7040b5d
LP
1081 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
1082
1083 if (mode != UNIT_CHECK) {
1084 c->nice = n;
b27b4b51 1085 unit_write_drop_in_private_format(u, mode, name, "Nice=%i", n);
c7040b5d
LP
1086 }
1087
1088 return 1;
1089
7f452159
LP
1090 } else if (streq(name, "IOSchedulingClass")) {
1091 int32_t q;
1092
1093 r = sd_bus_message_read(message, "i", &q);
1094 if (r < 0)
1095 return r;
1096
1097 if (!ioprio_class_is_valid(q))
1098 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
1099
1100 if (mode != UNIT_CHECK) {
1101 _cleanup_free_ char *s = NULL;
1102
1103 r = ioprio_class_to_string_alloc(q, &s);
1104 if (r < 0)
1105 return r;
1106
1107 c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
1108 c->ioprio_set = true;
1109
1110 unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
1111 }
1112
1113 return 1;
1114
1115 } else if (streq(name, "IOSchedulingPriority")) {
1116 int32_t p;
1117
1118 r = sd_bus_message_read(message, "i", &p);
1119 if (r < 0)
1120 return r;
1121
1122 if (!ioprio_priority_is_valid(p))
1123 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
1124
1125 if (mode != UNIT_CHECK) {
1126 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
1127 c->ioprio_set = true;
1128
1129 unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
1130 }
1131
1132 return 1;
1133
915e6d16 1134 } else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
602b8355 1135 const char *s;
9b15b784 1136
602b8355 1137 r = sd_bus_message_read(message, "s", &s);
9b15b784
LP
1138 if (r < 0)
1139 return r;
1140
602b8355
NC
1141 if (!path_is_absolute(s))
1142 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
9b15b784
LP
1143
1144 if (mode != UNIT_CHECK) {
5f5d8eab
LP
1145 if (streq(name, "TTYPath"))
1146 r = free_and_strdup(&c->tty_path, s);
915e6d16
LP
1147 else if (streq(name, "RootImage"))
1148 r = free_and_strdup(&c->root_image, s);
5f5d8eab
LP
1149 else {
1150 assert(streq(name, "RootDirectory"));
1151 r = free_and_strdup(&c->root_directory, s);
602b8355 1152 }
5f5d8eab
LP
1153 if (r < 0)
1154 return r;
9b15b784 1155
b27b4b51 1156 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
9b15b784
LP
1157 }
1158
1159 return 1;
1160
5f5d8eab
LP
1161 } else if (streq(name, "WorkingDirectory")) {
1162 const char *s;
1163 bool missing_ok;
1164
1165 r = sd_bus_message_read(message, "s", &s);
1166 if (r < 0)
1167 return r;
1168
1169 if (s[0] == '-') {
1170 missing_ok = true;
1171 s++;
1172 } else
1173 missing_ok = false;
1174
1175 if (!streq(s, "~") && !path_is_absolute(s))
1176 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
1177
1178 if (mode != UNIT_CHECK) {
1179 if (streq(s, "~")) {
1180 c->working_directory = mfree(c->working_directory);
1181 c->working_directory_home = true;
1182 } else {
1183 r = free_and_strdup(&c->working_directory, s);
1184 if (r < 0)
1185 return r;
1186
1187 c->working_directory_home = false;
1188 }
1189
1190 c->working_directory_missing_ok = missing_ok;
b27b4b51 1191 unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
5f5d8eab
LP
1192 }
1193
1194 return 1;
1195
9b15b784
LP
1196 } else if (streq(name, "StandardInput")) {
1197 const char *s;
1198 ExecInput p;
1199
1200 r = sd_bus_message_read(message, "s", &s);
1201 if (r < 0)
1202 return r;
1203
1204 p = exec_input_from_string(s);
1205 if (p < 0)
1206 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
1207
1208 if (mode != UNIT_CHECK) {
1209 c->std_input = p;
1210
b27b4b51 1211 unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s", exec_input_to_string(p));
9b15b784
LP
1212 }
1213
1214 return 1;
1215
9b15b784
LP
1216 } else if (streq(name, "StandardOutput")) {
1217 const char *s;
1218 ExecOutput p;
1219
1220 r = sd_bus_message_read(message, "s", &s);
1221 if (r < 0)
1222 return r;
1223
1224 p = exec_output_from_string(s);
1225 if (p < 0)
1226 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
1227
1228 if (mode != UNIT_CHECK) {
1229 c->std_output = p;
1230
b27b4b51 1231 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s", exec_output_to_string(p));
9b15b784
LP
1232 }
1233
1234 return 1;
1235
1236 } else if (streq(name, "StandardError")) {
1237 const char *s;
1238 ExecOutput p;
1239
1240 r = sd_bus_message_read(message, "s", &s);
1241 if (r < 0)
1242 return r;
1243
1244 p = exec_output_from_string(s);
1245 if (p < 0)
1246 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
1247
1248 if (mode != UNIT_CHECK) {
1249 c->std_error = p;
1250
b27b4b51 1251 unit_write_drop_in_private_format(u, mode, name, "StandardError=%s", exec_output_to_string(p));
9b15b784
LP
1252 }
1253
1254 return 1;
1255
52c239d7
LB
1256 } else if (STR_IN_SET(name,
1257 "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
1258 const char *s;
1259
1260 r = sd_bus_message_read(message, "s", &s);
1261 if (r < 0)
1262 return r;
1263
1264 if (!fdname_is_valid(s))
1265 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
1266
1267 if (mode != UNIT_CHECK) {
1268 if (streq(name, "StandardInputFileDescriptorName")) {
1269 c->std_input = EXEC_INPUT_NAMED_FD;
1270 r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], s);
1271 if (r < 0)
1272 return r;
1273 unit_write_drop_in_private_format(u, mode, name, "StandardInput=fd:%s", s);
1274 } else if (streq(name, "StandardOutputFileDescriptorName")) {
1275 c->std_output = EXEC_OUTPUT_NAMED_FD;
1276 r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], s);
1277 if (r < 0)
1278 return r;
1279 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=fd:%s", s);
1280 } else if (streq(name, "StandardErrorFileDescriptorName")) {
1281 c->std_error = EXEC_OUTPUT_NAMED_FD;
1282 r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], s);
1283 if (r < 0)
1284 return r;
1285 unit_write_drop_in_private_format(u, mode, name, "StandardError=fd:%s", s);
1286 }
1287 }
1288
1289 return 1;
1290
b9c50073
GP
1291 } else if (STR_IN_SET(name,
1292 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset",
d251207d 1293 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
29206d46 1294 "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
59eeb84b 1295 "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
5d997827 1296 "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS")) {
506711fd
LP
1297 int b;
1298
1299 r = sd_bus_message_read(message, "b", &b);
1300 if (r < 0)
1301 return r;
1302
1303 if (mode != UNIT_CHECK) {
b9c50073
GP
1304 if (streq(name, "IgnoreSIGPIPE"))
1305 c->ignore_sigpipe = b;
1306 else if (streq(name, "TTYVHangup"))
1307 c->tty_vhangup = b;
1308 else if (streq(name, "TTYReset"))
1309 c->tty_reset = b;
1310 else if (streq(name, "PrivateTmp"))
1311 c->private_tmp = b;
1312 else if (streq(name, "PrivateDevices"))
1313 c->private_devices = b;
1314 else if (streq(name, "PrivateNetwork"))
1315 c->private_network = b;
d251207d
LP
1316 else if (streq(name, "PrivateUsers"))
1317 c->private_users = b;
b9c50073
GP
1318 else if (streq(name, "NoNewPrivileges"))
1319 c->no_new_privileges = b;
047d9933
EV
1320 else if (streq(name, "SyslogLevelPrefix"))
1321 c->syslog_level_prefix = b;
f3e43635
TM
1322 else if (streq(name, "MemoryDenyWriteExecute"))
1323 c->memory_deny_write_execute = b;
f4170c67
LP
1324 else if (streq(name, "RestrictRealtime"))
1325 c->restrict_realtime = b;
29206d46
LP
1326 else if (streq(name, "DynamicUser"))
1327 c->dynamic_user = b;
00d9ef85
LP
1328 else if (streq(name, "RemoveIPC"))
1329 c->remove_ipc = b;
59eeb84b
LP
1330 else if (streq(name, "ProtectKernelTunables"))
1331 c->protect_kernel_tunables = b;
502d704e
DH
1332 else if (streq(name, "ProtectKernelModules"))
1333 c->protect_kernel_modules = b;
59eeb84b
LP
1334 else if (streq(name, "ProtectControlGroups"))
1335 c->protect_control_groups = b;
5d997827
LP
1336 else if (streq(name, "MountAPIVFS"))
1337 c->mount_apivfs = b;
b9c50073 1338
b27b4b51 1339 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, yes_no(b));
506711fd
LP
1340 }
1341
1342 return 1;
1343
1344 } else if (streq(name, "UtmpIdentifier")) {
1345 const char *id;
1346
1347 r = sd_bus_message_read(message, "s", &id);
1348 if (r < 0)
1349 return r;
1350
1351 if (mode != UNIT_CHECK) {
76736280
LP
1352 if (isempty(id))
1353 c->utmp_id = mfree(c->utmp_id);
1354 else if (free_and_strdup(&c->utmp_id, id) < 0)
1355 return -ENOMEM;
506711fd 1356
b27b4b51 1357 unit_write_drop_in_private_format(u, mode, name, "UtmpIdentifier=%s", strempty(id));
506711fd
LP
1358 }
1359
1360 return 1;
1361
1362 } else if (streq(name, "UtmpMode")) {
1363 const char *s;
1364 ExecUtmpMode m;
1365
1366 r = sd_bus_message_read(message, "s", &s);
1367 if (r < 0)
1368 return r;
1369
1370 m = exec_utmp_mode_from_string(s);
1371 if (m < 0)
1372 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
1373
1374 if (mode != UNIT_CHECK) {
1375 c->utmp_mode = m;
1376
b27b4b51 1377 unit_write_drop_in_private_format(u, mode, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
506711fd
LP
1378 }
1379
1380 return 1;
1381
1382 } else if (streq(name, "PAMName")) {
1383 const char *n;
1384
1385 r = sd_bus_message_read(message, "s", &n);
1386 if (r < 0)
1387 return r;
1388
1389 if (mode != UNIT_CHECK) {
76736280
LP
1390 if (isempty(n))
1391 c->pam_name = mfree(c->pam_name);
1392 else if (free_and_strdup(&c->pam_name, n) < 0)
1393 return -ENOMEM;
506711fd 1394
b27b4b51 1395 unit_write_drop_in_private_format(u, mode, name, "PAMName=%s", strempty(n));
506711fd
LP
1396 }
1397
1398 return 1;
1399
c7040b5d
LP
1400 } else if (streq(name, "Environment")) {
1401
f900f582 1402 _cleanup_strv_free_ char **l = NULL, **q = NULL;
c7040b5d
LP
1403
1404 r = sd_bus_message_read_strv(message, &l);
1405 if (r < 0)
1406 return r;
1407
1408 if (!strv_env_is_valid(l))
1409 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
1410
f900f582
ZJS
1411 r = unit_full_printf_strv(u, l, &q);
1412 if (r < 0)
1413 return r;
c7040b5d 1414
f900f582
ZJS
1415 if (mode != UNIT_CHECK) {
1416 if (strv_length(q) == 0) {
e9876fc9 1417 c->environment = strv_free(c->environment);
b27b4b51 1418 unit_write_drop_in_private_format(u, mode, name, "Environment=");
e9876fc9 1419 } else {
f900f582
ZJS
1420 _cleanup_free_ char *joined = NULL;
1421 char **e;
1422
1423 e = strv_env_merge(2, c->environment, q);
e9876fc9
EV
1424 if (!e)
1425 return -ENOMEM;
c7040b5d 1426
e9876fc9
EV
1427 strv_free(c->environment);
1428 c->environment = e;
c7040b5d 1429
f900f582
ZJS
1430 /* We write just the new settings out to file, with unresolved specifiers */
1431 joined = strv_join_quoted(q);
e9876fc9
EV
1432 if (!joined)
1433 return -ENOMEM;
1434
b27b4b51 1435 unit_write_drop_in_private_format(u, mode, name, "Environment=%s", joined);
e9876fc9 1436 }
c7040b5d
LP
1437 }
1438
d584f638
LP
1439 return 1;
1440
f1db3327
EV
1441 } else if (streq(name, "TimerSlackNSec")) {
1442
1443 nsec_t n;
1444
1445 r = sd_bus_message_read(message, "t", &n);
1446 if (r < 0)
1447 return r;
1448
1449 if (mode != UNIT_CHECK) {
1450 c->timer_slack_nsec = n;
b27b4b51 1451 unit_write_drop_in_private_format(u, mode, name, "TimerSlackNSec=" NSEC_FMT, n);
f1db3327
EV
1452 }
1453
1454 return 1;
1455
6b862936
EV
1456 } else if (streq(name, "OOMScoreAdjust")) {
1457 int oa;
1458
1459 r = sd_bus_message_read(message, "i", &oa);
1460 if (r < 0)
1461 return r;
1462
1463 if (!oom_score_adjust_is_valid(oa))
1464 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
1465
1466 if (mode != UNIT_CHECK) {
1467 c->oom_score_adjust = oa;
1468 c->oom_score_adjust_set = true;
b27b4b51 1469 unit_write_drop_in_private_format(u, mode, name, "OOMScoreAdjust=%i", oa);
6b862936
EV
1470 }
1471
1472 return 1;
1473
ceb728cf
NC
1474 } else if (streq(name, "EnvironmentFiles")) {
1475
1476 _cleanup_free_ char *joined = NULL;
1477 _cleanup_fclose_ FILE *f = NULL;
9b531f04 1478 _cleanup_strv_free_ char **l = NULL;
ceb728cf 1479 size_t size = 0;
2229f656 1480 char **i;
ceb728cf
NC
1481
1482 r = sd_bus_message_enter_container(message, 'a', "(sb)");
1483 if (r < 0)
1484 return r;
1485
1486 f = open_memstream(&joined, &size);
1487 if (!f)
1488 return -ENOMEM;
1489
2229f656 1490 STRV_FOREACH(i, c->environment_files)
b27b4b51 1491 fprintf(f, "EnvironmentFile=%s", *i);
ceb728cf
NC
1492
1493 while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
1494 const char *path;
1495 int b;
1496
ceb728cf
NC
1497 r = sd_bus_message_read(message, "sb", &path, &b);
1498 if (r < 0)
1499 return r;
1500
1501 r = sd_bus_message_exit_container(message);
1502 if (r < 0)
1503 return r;
1504
d2d6c096
LP
1505 if (!path_is_absolute(path))
1506 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
ceb728cf
NC
1507
1508 if (mode != UNIT_CHECK) {
ceb728cf
NC
1509 char *buf = NULL;
1510
605405c6 1511 buf = strjoin(b ? "-" : "", path);
2229f656 1512 if (!buf)
ceb728cf
NC
1513 return -ENOMEM;
1514
b27b4b51 1515 fprintf(f, "EnvironmentFile=%s", buf);
ceb728cf 1516
2229f656 1517 r = strv_consume(&l, buf);
ceb728cf
NC
1518 if (r < 0)
1519 return r;
1520 }
1521 }
1522 if (r < 0)
1523 return r;
1524
b0830e21
LP
1525 r = sd_bus_message_exit_container(message);
1526 if (r < 0)
1527 return r;
1528
2229f656
LP
1529 r = fflush_and_check(f);
1530 if (r < 0)
1531 return r;
ceb728cf 1532
2229f656
LP
1533 if (mode != UNIT_CHECK) {
1534 if (strv_isempty(l)) {
1535 c->environment_files = strv_free(c->environment_files);
b27b4b51 1536 unit_write_drop_in_private(u, mode, name, "EnvironmentFile=");
2229f656
LP
1537 } else {
1538 r = strv_extend_strv(&c->environment_files, l, true);
1539 if (r < 0)
1540 return r;
1541
ceb728cf 1542 unit_write_drop_in_private(u, mode, name, joined);
2229f656
LP
1543 }
1544 }
ceb728cf 1545
ceb728cf
NC
1546 return 1;
1547
b4c14404
FB
1548 } else if (streq(name, "PassEnvironment")) {
1549
1550 _cleanup_strv_free_ char **l = NULL;
1551
1552 r = sd_bus_message_read_strv(message, &l);
1553 if (r < 0)
1554 return r;
1555
1556 if (!strv_env_name_is_valid(l))
1557 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment block.");
1558
1559 if (mode != UNIT_CHECK) {
1560 if (strv_isempty(l)) {
1561 c->pass_environment = strv_free(c->pass_environment);
b27b4b51 1562 unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=");
b4c14404
FB
1563 } else {
1564 _cleanup_free_ char *joined = NULL;
1565
1566 r = strv_extend_strv(&c->pass_environment, l, true);
1567 if (r < 0)
1568 return r;
1569
1570 joined = strv_join_quoted(c->pass_environment);
1571 if (!joined)
1572 return -ENOMEM;
1573
b27b4b51 1574 unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=%s", joined);
b4c14404
FB
1575 }
1576 }
1577
1578 return 1;
1579
2a624c36
AP
1580 } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
1581 "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
08596068
EV
1582 _cleanup_strv_free_ char **l = NULL;
1583 char ***dirs;
1584 char **p;
1585
1586 r = sd_bus_message_read_strv(message, &l);
1587 if (r < 0)
1588 return r;
1589
1590 STRV_FOREACH(p, l) {
20b7a007
LP
1591 const char *i = *p;
1592 size_t offset;
1593
1594 if (!utf8_is_valid(i))
08596068
EV
1595 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
1596
20b7a007
LP
1597 offset = i[0] == '-';
1598 offset += i[offset] == '+';
1599 if (!path_is_absolute(i + offset))
08596068
EV
1600 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
1601 }
1602
1603 if (mode != UNIT_CHECK) {
1604 _cleanup_free_ char *joined = NULL;
1605
c4b41707
AP
1606 if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
1607 dirs = &c->read_write_paths;
1608 else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
1609 dirs = &c->read_only_paths;
1610 else /* "InaccessiblePaths" */
1611 dirs = &c->inaccessible_paths;
08596068
EV
1612
1613 if (strv_length(l) == 0) {
1614 *dirs = strv_free(*dirs);
b27b4b51 1615 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
08596068
EV
1616 } else {
1617 r = strv_extend_strv(dirs, l, true);
08596068
EV
1618 if (r < 0)
1619 return -ENOMEM;
1620
1621 joined = strv_join_quoted(*dirs);
1622 if (!joined)
1623 return -ENOMEM;
1624
b27b4b51 1625 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
08596068
EV
1626 }
1627
1628 }
1629
1630 return 1;
1631
5664e6cf
EV
1632 } else if (streq(name, "ProtectSystem")) {
1633 const char *s;
1634 ProtectSystem ps;
1635
1636 r = sd_bus_message_read(message, "s", &s);
1637 if (r < 0)
1638 return r;
1639
1640 r = parse_boolean(s);
1641 if (r > 0)
1642 ps = PROTECT_SYSTEM_YES;
1643 else if (r == 0)
1644 ps = PROTECT_SYSTEM_NO;
1645 else {
1646 ps = protect_system_from_string(s);
1647 if (ps < 0)
1648 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value");
1649 }
1650
1651 if (mode != UNIT_CHECK) {
1652 c->protect_system = ps;
b27b4b51 1653 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
5664e6cf
EV
1654 }
1655
1656 return 1;
1657
eff58074
EV
1658 } else if (streq(name, "ProtectHome")) {
1659 const char *s;
1660 ProtectHome ph;
1661
1662 r = sd_bus_message_read(message, "s", &s);
1663 if (r < 0)
1664 return r;
1665
1666 r = parse_boolean(s);
1667 if (r > 0)
1668 ph = PROTECT_HOME_YES;
1669 else if (r == 0)
1670 ph = PROTECT_HOME_NO;
1671 else {
1672 ph = protect_home_from_string(s);
1673 if (ph < 0)
1674 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value");
1675 }
1676
1677 if (mode != UNIT_CHECK) {
1678 c->protect_home = ph;
b27b4b51 1679 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
eff58074
EV
1680 }
1681
1682 return 1;
1683
53f47dfc
YW
1684 } else if (streq(name, "RuntimeDirectoryPreserve")) {
1685 const char *s;
1686 ExecPreserveMode m;
1687
1688 r = sd_bus_message_read(message, "s", &s);
1689 if (r < 0)
1690 return r;
1691
1692 m = exec_preserve_mode_from_string(s);
1693 if (m < 0)
1694 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode");
1695
1696 if (mode != UNIT_CHECK) {
1697 c->runtime_directory_preserve_mode = m;
1698
1699 unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
1700 }
1701
1702 return 1;
1703
1704 } else if (streq(name, "RuntimeDirectoryMode")) {
1705 mode_t m;
1706
1707 r = sd_bus_message_read(message, "u", &m);
1708 if (r < 0)
1709 return r;
1710
1711 if (mode != UNIT_CHECK) {
1712 c->runtime_directory_mode = m;
1713
1714 unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryMode=%040o", m);
1715 }
1716
1717 return 1;
1718
fa21b5e3
EV
1719 } else if (streq(name, "RuntimeDirectory")) {
1720 _cleanup_strv_free_ char **l = NULL;
1721 char **p;
1722
1723 r = sd_bus_message_read_strv(message, &l);
1724 if (r < 0)
1725 return r;
1726
1727 STRV_FOREACH(p, l) {
1728 if (!filename_is_valid(*p))
1729 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Runtime directory is not valid %s", *p);
1730 }
1731
1732 if (mode != UNIT_CHECK) {
1733 _cleanup_free_ char *joined = NULL;
1734
1735 if (strv_isempty(l)) {
1736 c->runtime_directory = strv_free(c->runtime_directory);
b27b4b51 1737 unit_write_drop_in_private_format(u, mode, name, "%s=", name);
fa21b5e3
EV
1738 } else {
1739 r = strv_extend_strv(&c->runtime_directory, l, true);
1740
1741 if (r < 0)
1742 return -ENOMEM;
1743
1744 joined = strv_join_quoted(c->runtime_directory);
1745 if (!joined)
1746 return -ENOMEM;
1747
b27b4b51 1748 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined);
fa21b5e3
EV
1749 }
1750 }
1751
1752 return 1;
1753
186ad4b1
JB
1754 } else if (streq(name, "SELinuxContext")) {
1755 const char *s;
1756
1757 r = sd_bus_message_read(message, "s", &s);
1758 if (r < 0)
1759 return r;
1760
1761 if (mode != UNIT_CHECK) {
4e282d11
JB
1762 if (isempty(s))
1763 c->selinux_context = mfree(c->selinux_context);
1764 else if (free_and_strdup(&c->selinux_context, s) < 0)
1765 return -ENOMEM;
186ad4b1 1766
b27b4b51 1767 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, strempty(s));
186ad4b1
JB
1768 }
1769
1770 return 1;
add00535
LP
1771 } else if (streq(name, "RestrictNamespaces")) {
1772 uint64_t flags;
186ad4b1 1773
add00535
LP
1774 r = sd_bus_message_read(message, "t", &flags);
1775 if (r < 0)
1776 return r;
1777 if ((flags & NAMESPACE_FLAGS_ALL) != flags)
1778 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
1779
1780 if (mode != UNIT_CHECK) {
1781 _cleanup_free_ char *s = NULL;
1782
1783 r = namespace_flag_to_string_many(flags, &s);
1784 if (r < 0)
1785 return r;
1786
1787 c->restrict_namespaces = flags;
1788 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s);
1789 }
1790
1791 return 1;
83555251
LP
1792 } else if (streq(name, "MountFlags")) {
1793 uint64_t flags;
1794
1795 r = sd_bus_message_read(message, "t", &flags);
1796 if (r < 0)
1797 return r;
1798 if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
1799 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
cab2aca3 1800
83555251
LP
1801 if (mode != UNIT_CHECK) {
1802 c->mount_flags = flags;
1803
c7383828 1804 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, mount_propagation_flags_to_string(flags));
83555251
LP
1805 }
1806
d2d6c096
LP
1807 return 1;
1808 } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
1809 unsigned empty = true;
1810
1811 r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
1812 if (r < 0)
1813 return r;
1814
1815 while ((r = sd_bus_message_enter_container(message, 'r', "ssbt")) > 0) {
1816 const char *source, *destination;
1817 int ignore_enoent;
1818 uint64_t mount_flags;
1819
1820 r = sd_bus_message_read(message, "ssbt", &source, &destination, &ignore_enoent, &mount_flags);
1821 if (r < 0)
1822 return r;
1823
1824 r = sd_bus_message_exit_container(message);
1825 if (r < 0)
1826 return r;
1827
1828 if (!path_is_absolute(source))
1829 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
1830 if (!path_is_absolute(destination))
91d910e3 1831 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
d2d6c096
LP
1832 if (!IN_SET(mount_flags, 0, MS_REC))
1833 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
1834
1835 if (mode != UNIT_CHECK) {
1836 r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
1837 &(BindMount) {
1838 .source = strdup(source),
1839 .destination = strdup(destination),
1840 .read_only = !!strstr(name, "ReadOnly"),
1841 .recursive = !!(mount_flags & MS_REC),
1842 .ignore_enoent = ignore_enoent,
1843 });
1844 if (r < 0)
1845 return r;
1846
1847 unit_write_drop_in_private_format(
1848 u, mode, name,
1849 "%s=%s%s:%s:%s",
1850 name,
1851 ignore_enoent ? "-" : "",
1852 source,
1853 destination,
1854 (mount_flags & MS_REC) ? "rbind" : "norbind");
1855 }
1856
1857 empty = false;
1858 }
1859 if (r < 0)
1860 return r;
1861
1862 r = sd_bus_message_exit_container(message);
1863 if (r < 0)
1864 return r;
1865
1866 if (empty) {
1867 bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
1868 c->bind_mounts = NULL;
1869 c->n_bind_mounts = 0;
1870 }
1871
83555251
LP
1872 return 1;
1873 }
d2d6c096 1874
cab2aca3
LP
1875 ri = rlimit_from_string(name);
1876 if (ri < 0) {
1877 soft = endswith(name, "Soft");
1878 if (soft) {
1879 const char *n;
1880
1881 n = strndupa(name, soft - name);
1882 ri = rlimit_from_string(n);
1883 if (ri >= 0)
1884 name = n;
1885
1886 }
1887 }
1888
1889 if (ri >= 0) {
d584f638
LP
1890 uint64_t rl;
1891 rlim_t x;
1892
1893 r = sd_bus_message_read(message, "t", &rl);
1894 if (r < 0)
1895 return r;
1896
1897 if (rl == (uint64_t) -1)
1898 x = RLIM_INFINITY;
1899 else {
1900 x = (rlim_t) rl;
1901
1902 if ((uint64_t) x != rl)
1903 return -ERANGE;
1904 }
1905
1906 if (mode != UNIT_CHECK) {
cab2aca3
LP
1907 _cleanup_free_ char *f = NULL;
1908 struct rlimit nl;
1909
1910 if (c->rlimit[ri]) {
1911 nl = *c->rlimit[ri];
1912
1913 if (soft)
1914 nl.rlim_cur = x;
1915 else
1916 nl.rlim_max = x;
1917 } else
1918 /* When the resource limit is not initialized yet, then assign the value to both fields */
1919 nl = (struct rlimit) {
1920 .rlim_cur = x,
1921 .rlim_max = x,
1922 };
1923
1924 r = rlimit_format(&nl, &f);
1925 if (r < 0)
1926 return r;
d584f638 1927
cab2aca3
LP
1928 if (c->rlimit[ri])
1929 *c->rlimit[ri] = nl;
1930 else {
1931 c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
1932 if (!c->rlimit[ri])
d584f638
LP
1933 return -ENOMEM;
1934 }
1935
b27b4b51 1936 unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, f);
d584f638
LP
1937 }
1938
c7040b5d
LP
1939 return 1;
1940 }
1941
1942 return 0;
1943}