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