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