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