1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <sys/prctl.h>
28 #include "alloc-util.h"
31 #include "capability-util.h"
32 #include "dbus-execute.h"
34 #include "errno-list.h"
40 #include "journal-util.h"
42 #include "mount-util.h"
43 #include "namespace.h"
44 #include "parse-util.h"
45 #include "path-util.h"
46 #include "process-util.h"
47 #include "rlimit-util.h"
49 #include "seccomp-util.h"
51 #include "securebits-util.h"
53 #include "syslog-util.h"
54 #include "unit-printf.h"
55 #include "user-util.h"
58 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output
, exec_output
, ExecOutput
);
59 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input
, exec_input
, ExecInput
);
61 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode
, exec_utmp_mode
, ExecUtmpMode
);
62 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode
, exec_preserve_mode
, ExecPreserveMode
);
63 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode
, exec_keyring_mode
, ExecKeyringMode
);
65 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home
, protect_home
, ProtectHome
);
66 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system
, protect_system
, ProtectSystem
);
68 static int property_get_environment_files(
71 const char *interface
,
73 sd_bus_message
*reply
,
75 sd_bus_error
*error
) {
77 ExecContext
*c
= userdata
;
85 r
= sd_bus_message_open_container(reply
, 'a', "(sb)");
89 STRV_FOREACH(j
, c
->environment_files
) {
92 r
= sd_bus_message_append(reply
, "(sb)", fn
[0] == '-' ? fn
+ 1 : fn
, fn
[0] == '-');
97 return sd_bus_message_close_container(reply
);
100 static int property_get_oom_score_adjust(
103 const char *interface
,
104 const char *property
,
105 sd_bus_message
*reply
,
107 sd_bus_error
*error
) {
110 ExecContext
*c
= userdata
;
117 if (c
->oom_score_adjust_set
)
118 n
= c
->oom_score_adjust
;
120 _cleanup_free_
char *t
= NULL
;
123 if (read_one_line_file("/proc/self/oom_score_adj", &t
) >= 0)
127 return sd_bus_message_append(reply
, "i", n
);
130 static int property_get_nice(
133 const char *interface
,
134 const char *property
,
135 sd_bus_message
*reply
,
137 sd_bus_error
*error
) {
140 ExecContext
*c
= userdata
;
151 n
= getpriority(PRIO_PROCESS
, 0);
156 return sd_bus_message_append(reply
, "i", n
);
159 static int property_get_ioprio(
162 const char *interface
,
163 const char *property
,
164 sd_bus_message
*reply
,
166 sd_bus_error
*error
) {
169 ExecContext
*c
= userdata
;
175 return sd_bus_message_append(reply
, "i", exec_context_get_effective_ioprio(c
));
178 static int property_get_ioprio_class(
181 const char *interface
,
182 const char *property
,
183 sd_bus_message
*reply
,
185 sd_bus_error
*error
) {
188 ExecContext
*c
= userdata
;
194 return sd_bus_message_append(reply
, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c
)));
197 static int property_get_ioprio_priority(
200 const char *interface
,
201 const char *property
,
202 sd_bus_message
*reply
,
204 sd_bus_error
*error
) {
207 ExecContext
*c
= userdata
;
213 return sd_bus_message_append(reply
, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c
)));
216 static int property_get_cpu_sched_policy(
219 const char *interface
,
220 const char *property
,
221 sd_bus_message
*reply
,
223 sd_bus_error
*error
) {
225 ExecContext
*c
= userdata
;
232 if (c
->cpu_sched_set
)
233 n
= c
->cpu_sched_policy
;
235 n
= sched_getscheduler(0);
240 return sd_bus_message_append(reply
, "i", n
);
243 static int property_get_cpu_sched_priority(
246 const char *interface
,
247 const char *property
,
248 sd_bus_message
*reply
,
250 sd_bus_error
*error
) {
252 ExecContext
*c
= userdata
;
259 if (c
->cpu_sched_set
)
260 n
= c
->cpu_sched_priority
;
262 struct sched_param p
= {};
264 if (sched_getparam(0, &p
) >= 0)
265 n
= p
.sched_priority
;
270 return sd_bus_message_append(reply
, "i", n
);
273 static int property_get_cpu_affinity(
276 const char *interface
,
277 const char *property
,
278 sd_bus_message
*reply
,
280 sd_bus_error
*error
) {
282 ExecContext
*c
= userdata
;
289 return sd_bus_message_append_array(reply
, 'y', c
->cpuset
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
));
291 return sd_bus_message_append_array(reply
, 'y', NULL
, 0);
294 static int property_get_timer_slack_nsec(
297 const char *interface
,
298 const char *property
,
299 sd_bus_message
*reply
,
301 sd_bus_error
*error
) {
303 ExecContext
*c
= userdata
;
310 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
311 u
= (uint64_t) c
->timer_slack_nsec
;
313 u
= (uint64_t) prctl(PR_GET_TIMERSLACK
);
315 return sd_bus_message_append(reply
, "t", u
);
318 static int property_get_capability_bounding_set(
321 const char *interface
,
322 const char *property
,
323 sd_bus_message
*reply
,
325 sd_bus_error
*error
) {
327 ExecContext
*c
= userdata
;
333 return sd_bus_message_append(reply
, "t", c
->capability_bounding_set
);
336 static int property_get_ambient_capabilities(
339 const char *interface
,
340 const char *property
,
341 sd_bus_message
*reply
,
343 sd_bus_error
*error
) {
345 ExecContext
*c
= userdata
;
351 return sd_bus_message_append(reply
, "t", c
->capability_ambient_set
);
354 static int property_get_empty_string(
357 const char *interface
,
358 const char *property
,
359 sd_bus_message
*reply
,
361 sd_bus_error
*error
) {
366 return sd_bus_message_append(reply
, "s", "");
369 static int property_get_syscall_filter(
372 const char *interface
,
373 const char *property
,
374 sd_bus_message
*reply
,
376 sd_bus_error
*error
) {
378 ExecContext
*c
= userdata
;
379 _cleanup_strv_free_
char **l
= NULL
;
391 r
= sd_bus_message_open_container(reply
, 'r', "bas");
395 r
= sd_bus_message_append(reply
, "b", c
->syscall_whitelist
);
400 HASHMAP_FOREACH_KEY(val
, id
, c
->syscall_filter
, i
) {
401 _cleanup_free_
char *name
= NULL
;
402 const char *e
= NULL
;
404 int num
= PTR_TO_INT(val
);
406 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
411 e
= errno_to_name(num
);
413 s
= strjoin(name
, ":", e
);
417 r
= asprintf(&s
, "%s:%d", name
, num
);
426 r
= strv_consume(&l
, s
);
434 r
= sd_bus_message_append_strv(reply
, l
);
438 return sd_bus_message_close_container(reply
);
441 static int property_get_syscall_archs(
444 const char *interface
,
445 const char *property
,
446 sd_bus_message
*reply
,
448 sd_bus_error
*error
) {
450 ExecContext
*c
= userdata
;
451 _cleanup_strv_free_
char **l
= NULL
;
464 SET_FOREACH(id
, c
->syscall_archs
, i
) {
467 name
= seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1);
471 r
= strv_extend(&l
, name
);
479 r
= sd_bus_message_append_strv(reply
, l
);
486 static int property_get_syscall_errno(
489 const char *interface
,
490 const char *property
,
491 sd_bus_message
*reply
,
493 sd_bus_error
*error
) {
495 ExecContext
*c
= userdata
;
501 return sd_bus_message_append(reply
, "i", (int32_t) c
->syscall_errno
);
504 static int property_get_selinux_context(
507 const char *interface
,
508 const char *property
,
509 sd_bus_message
*reply
,
511 sd_bus_error
*error
) {
513 ExecContext
*c
= userdata
;
519 return sd_bus_message_append(reply
, "(bs)", c
->selinux_context_ignore
, c
->selinux_context
);
522 static int property_get_apparmor_profile(
525 const char *interface
,
526 const char *property
,
527 sd_bus_message
*reply
,
529 sd_bus_error
*error
) {
531 ExecContext
*c
= userdata
;
537 return sd_bus_message_append(reply
, "(bs)", c
->apparmor_profile_ignore
, c
->apparmor_profile
);
540 static int property_get_smack_process_label(
543 const char *interface
,
544 const char *property
,
545 sd_bus_message
*reply
,
547 sd_bus_error
*error
) {
549 ExecContext
*c
= userdata
;
555 return sd_bus_message_append(reply
, "(bs)", c
->smack_process_label_ignore
, c
->smack_process_label
);
558 static int property_get_personality(
561 const char *interface
,
562 const char *property
,
563 sd_bus_message
*reply
,
565 sd_bus_error
*error
) {
567 ExecContext
*c
= userdata
;
573 return sd_bus_message_append(reply
, "s", personality_to_string(c
->personality
));
576 static int property_get_address_families(
579 const char *interface
,
580 const char *property
,
581 sd_bus_message
*reply
,
583 sd_bus_error
*error
) {
585 ExecContext
*c
= userdata
;
586 _cleanup_strv_free_
char **l
= NULL
;
595 r
= sd_bus_message_open_container(reply
, 'r', "bas");
599 r
= sd_bus_message_append(reply
, "b", c
->address_families_whitelist
);
603 SET_FOREACH(af
, c
->address_families
, i
) {
606 name
= af_to_name(PTR_TO_INT(af
));
610 r
= strv_extend(&l
, name
);
617 r
= sd_bus_message_append_strv(reply
, l
);
621 return sd_bus_message_close_container(reply
);
624 static int property_get_working_directory(
627 const char *interface
,
628 const char *property
,
629 sd_bus_message
*reply
,
631 sd_bus_error
*error
) {
633 ExecContext
*c
= userdata
;
640 if (c
->working_directory_home
)
643 wd
= c
->working_directory
;
645 if (c
->working_directory_missing_ok
)
646 wd
= strjoina("!", wd
);
648 return sd_bus_message_append(reply
, "s", wd
);
651 static int property_get_syslog_level(
654 const char *interface
,
655 const char *property
,
656 sd_bus_message
*reply
,
658 sd_bus_error
*error
) {
660 ExecContext
*c
= userdata
;
666 return sd_bus_message_append(reply
, "i", LOG_PRI(c
->syslog_priority
));
669 static int property_get_syslog_facility(
672 const char *interface
,
673 const char *property
,
674 sd_bus_message
*reply
,
676 sd_bus_error
*error
) {
678 ExecContext
*c
= userdata
;
684 return sd_bus_message_append(reply
, "i", LOG_FAC(c
->syslog_priority
));
687 static int property_get_input_fdname(
690 const char *interface
,
691 const char *property
,
692 sd_bus_message
*reply
,
694 sd_bus_error
*error
) {
696 ExecContext
*c
= userdata
;
704 name
= exec_context_fdname(c
, STDIN_FILENO
);
706 return sd_bus_message_append(reply
, "s", name
);
709 static int property_get_output_fdname(
712 const char *interface
,
713 const char *property
,
714 sd_bus_message
*reply
,
716 sd_bus_error
*error
) {
718 ExecContext
*c
= userdata
;
719 const char *name
= NULL
;
726 if (c
->std_output
== EXEC_OUTPUT_NAMED_FD
&& streq(property
, "StandardOutputFileDescriptorName"))
727 name
= exec_context_fdname(c
, STDOUT_FILENO
);
728 else if (c
->std_error
== EXEC_OUTPUT_NAMED_FD
&& streq(property
, "StandardErrorFileDescriptorName"))
729 name
= exec_context_fdname(c
, STDERR_FILENO
);
731 return sd_bus_message_append(reply
, "s", name
);
734 static int property_get_bind_paths(
737 const char *interface
,
738 const char *property
,
739 sd_bus_message
*reply
,
741 sd_bus_error
*error
) {
743 ExecContext
*c
= userdata
;
753 ro
= !!strstr(property
, "ReadOnly");
755 r
= sd_bus_message_open_container(reply
, 'a', "(ssbt)");
759 for (i
= 0; i
< c
->n_bind_mounts
; i
++) {
761 if (ro
!= c
->bind_mounts
[i
].read_only
)
764 r
= sd_bus_message_append(
766 c
->bind_mounts
[i
].source
,
767 c
->bind_mounts
[i
].destination
,
768 c
->bind_mounts
[i
].ignore_enoent
,
769 c
->bind_mounts
[i
].recursive
? (uint64_t) MS_REC
: (uint64_t) 0);
774 return sd_bus_message_close_container(reply
);
777 static int property_get_log_extra_fields(
780 const char *interface
,
781 const char *property
,
782 sd_bus_message
*reply
,
784 sd_bus_error
*error
) {
786 ExecContext
*c
= userdata
;
795 r
= sd_bus_message_open_container(reply
, 'a', "ay");
799 for (i
= 0; i
< c
->n_log_extra_fields
; i
++) {
800 r
= sd_bus_message_append_array(reply
, 'y', c
->log_extra_fields
[i
].iov_base
, c
->log_extra_fields
[i
].iov_len
);
805 return sd_bus_message_close_container(reply
);
808 const sd_bus_vtable bus_exec_vtable
[] = {
809 SD_BUS_VTABLE_START(0),
810 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(ExecContext
, environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
811 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
812 SD_BUS_PROPERTY("PassEnvironment", "as", NULL
, offsetof(ExecContext
, pass_environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
813 SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL
, offsetof(ExecContext
, unset_environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
814 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode
, offsetof(ExecContext
, umask
), SD_BUS_VTABLE_PROPERTY_CONST
),
815 SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CPU
]), SD_BUS_VTABLE_PROPERTY_CONST
),
816 SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CPU
]), SD_BUS_VTABLE_PROPERTY_CONST
),
817 SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_FSIZE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
818 SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_FSIZE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
819 SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_DATA
]), SD_BUS_VTABLE_PROPERTY_CONST
),
820 SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_DATA
]), SD_BUS_VTABLE_PROPERTY_CONST
),
821 SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_STACK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
822 SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_STACK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
823 SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CORE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
824 SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CORE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
825 SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RSS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
826 SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RSS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
827 SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NOFILE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
828 SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NOFILE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
829 SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_AS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
830 SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_AS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
831 SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NPROC
]), SD_BUS_VTABLE_PROPERTY_CONST
),
832 SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NPROC
]), SD_BUS_VTABLE_PROPERTY_CONST
),
833 SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MEMLOCK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
834 SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MEMLOCK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
835 SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_LOCKS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
836 SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_LOCKS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
837 SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_SIGPENDING
]), SD_BUS_VTABLE_PROPERTY_CONST
),
838 SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_SIGPENDING
]), SD_BUS_VTABLE_PROPERTY_CONST
),
839 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MSGQUEUE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
840 SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MSGQUEUE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
841 SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NICE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
842 SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NICE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
843 SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTPRIO
]), SD_BUS_VTABLE_PROPERTY_CONST
),
844 SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTPRIO
]), SD_BUS_VTABLE_PROPERTY_CONST
),
845 SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTTIME
]), SD_BUS_VTABLE_PROPERTY_CONST
),
846 SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTTIME
]), SD_BUS_VTABLE_PROPERTY_CONST
),
847 SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
848 SD_BUS_PROPERTY("RootDirectory", "s", NULL
, offsetof(ExecContext
, root_directory
), SD_BUS_VTABLE_PROPERTY_CONST
),
849 SD_BUS_PROPERTY("RootImage", "s", NULL
, offsetof(ExecContext
, root_image
), SD_BUS_VTABLE_PROPERTY_CONST
),
850 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
851 SD_BUS_PROPERTY("Nice", "i", property_get_nice
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
852 SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
853 SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
854 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
855 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
856 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
857 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
858 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool
, offsetof(ExecContext
, cpu_sched_reset_on_fork
), SD_BUS_VTABLE_PROPERTY_CONST
),
859 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool
, offsetof(ExecContext
, non_blocking
), SD_BUS_VTABLE_PROPERTY_CONST
),
860 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input
, offsetof(ExecContext
, std_input
), SD_BUS_VTABLE_PROPERTY_CONST
),
861 SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_input_fdname
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
862 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output
, offsetof(ExecContext
, std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
863 SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_output_fdname
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
864 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output
, offsetof(ExecContext
, std_error
), SD_BUS_VTABLE_PROPERTY_CONST
),
865 SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_output_fdname
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
866 SD_BUS_PROPERTY("TTYPath", "s", NULL
, offsetof(ExecContext
, tty_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
867 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_reset
), SD_BUS_VTABLE_PROPERTY_CONST
),
868 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_vhangup
), SD_BUS_VTABLE_PROPERTY_CONST
),
869 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_vt_disallocate
), SD_BUS_VTABLE_PROPERTY_CONST
),
870 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int
, offsetof(ExecContext
, syslog_priority
), SD_BUS_VTABLE_PROPERTY_CONST
),
871 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL
, offsetof(ExecContext
, syslog_identifier
), SD_BUS_VTABLE_PROPERTY_CONST
),
872 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool
, offsetof(ExecContext
, syslog_level_prefix
), SD_BUS_VTABLE_PROPERTY_CONST
),
873 SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
874 SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
875 SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int
, offsetof(ExecContext
, log_level_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
876 SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
877 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int
, offsetof(ExecContext
, secure_bits
), SD_BUS_VTABLE_PROPERTY_CONST
),
878 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
879 SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
880 SD_BUS_PROPERTY("User", "s", NULL
, offsetof(ExecContext
, user
), SD_BUS_VTABLE_PROPERTY_CONST
),
881 SD_BUS_PROPERTY("Group", "s", NULL
, offsetof(ExecContext
, group
), SD_BUS_VTABLE_PROPERTY_CONST
),
882 SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool
, offsetof(ExecContext
, dynamic_user
), SD_BUS_VTABLE_PROPERTY_CONST
),
883 SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool
, offsetof(ExecContext
, remove_ipc
), SD_BUS_VTABLE_PROPERTY_CONST
),
884 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL
, offsetof(ExecContext
, supplementary_groups
), SD_BUS_VTABLE_PROPERTY_CONST
),
885 SD_BUS_PROPERTY("PAMName", "s", NULL
, offsetof(ExecContext
, pam_name
), SD_BUS_VTABLE_PROPERTY_CONST
),
886 SD_BUS_PROPERTY("ReadWritePaths", "as", NULL
, offsetof(ExecContext
, read_write_paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
887 SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL
, offsetof(ExecContext
, read_only_paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
888 SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL
, offsetof(ExecContext
, inaccessible_paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
889 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong
, offsetof(ExecContext
, mount_flags
), SD_BUS_VTABLE_PROPERTY_CONST
),
890 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool
, offsetof(ExecContext
, private_tmp
), SD_BUS_VTABLE_PROPERTY_CONST
),
891 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool
, offsetof(ExecContext
, private_devices
), SD_BUS_VTABLE_PROPERTY_CONST
),
892 SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool
, offsetof(ExecContext
, protect_kernel_tunables
), SD_BUS_VTABLE_PROPERTY_CONST
),
893 SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool
, offsetof(ExecContext
, protect_kernel_modules
), SD_BUS_VTABLE_PROPERTY_CONST
),
894 SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool
, offsetof(ExecContext
, protect_control_groups
), SD_BUS_VTABLE_PROPERTY_CONST
),
895 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool
, offsetof(ExecContext
, private_network
), SD_BUS_VTABLE_PROPERTY_CONST
),
896 SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool
, offsetof(ExecContext
, private_users
), SD_BUS_VTABLE_PROPERTY_CONST
),
897 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home
, offsetof(ExecContext
, protect_home
), SD_BUS_VTABLE_PROPERTY_CONST
),
898 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system
, offsetof(ExecContext
, protect_system
), SD_BUS_VTABLE_PROPERTY_CONST
),
899 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool
, offsetof(ExecContext
, same_pgrp
), SD_BUS_VTABLE_PROPERTY_CONST
),
900 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL
, offsetof(ExecContext
, utmp_id
), SD_BUS_VTABLE_PROPERTY_CONST
),
901 SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode
, offsetof(ExecContext
, utmp_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
902 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
903 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
904 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
905 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool
, offsetof(ExecContext
, ignore_sigpipe
), SD_BUS_VTABLE_PROPERTY_CONST
),
906 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool
, offsetof(ExecContext
, no_new_privileges
), SD_BUS_VTABLE_PROPERTY_CONST
),
907 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
908 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
909 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
910 SD_BUS_PROPERTY("Personality", "s", property_get_personality
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
911 SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool
, offsetof(ExecContext
, lock_personality
), SD_BUS_VTABLE_PROPERTY_CONST
),
912 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
913 SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode
, offsetof(ExecContext
, runtime_directory_preserve_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
914 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_RUNTIME
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
915 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_RUNTIME
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
916 SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_STATE
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
917 SD_BUS_PROPERTY("StateDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_STATE
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
918 SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CACHE
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
919 SD_BUS_PROPERTY("CacheDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CACHE
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
920 SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_LOGS
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
921 SD_BUS_PROPERTY("LogsDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_LOGS
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
922 SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CONFIGURATION
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
923 SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CONFIGURATION
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
924 SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool
, offsetof(ExecContext
, memory_deny_write_execute
), SD_BUS_VTABLE_PROPERTY_CONST
),
925 SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool
, offsetof(ExecContext
, restrict_realtime
), SD_BUS_VTABLE_PROPERTY_CONST
),
926 SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong
, offsetof(ExecContext
, restrict_namespaces
), SD_BUS_VTABLE_PROPERTY_CONST
),
927 SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
928 SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
929 SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool
, offsetof(ExecContext
, mount_apivfs
), SD_BUS_VTABLE_PROPERTY_CONST
),
930 SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode
, offsetof(ExecContext
, keyring_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
932 /* Obsolete/redundant properties: */
933 SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string
, 0, SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
934 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL
, offsetof(ExecContext
, read_write_paths
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
935 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL
, offsetof(ExecContext
, read_only_paths
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
936 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL
, offsetof(ExecContext
, inaccessible_paths
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
937 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio
, 0, SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
942 static int append_exec_command(sd_bus_message
*reply
, ExecCommand
*c
) {
951 r
= sd_bus_message_open_container(reply
, 'r', "sasbttttuii");
955 r
= sd_bus_message_append(reply
, "s", c
->path
);
959 r
= sd_bus_message_append_strv(reply
, c
->argv
);
963 r
= sd_bus_message_append(reply
, "bttttuii",
964 !!(c
->flags
& EXEC_COMMAND_IGNORE_FAILURE
),
965 c
->exec_status
.start_timestamp
.realtime
,
966 c
->exec_status
.start_timestamp
.monotonic
,
967 c
->exec_status
.exit_timestamp
.realtime
,
968 c
->exec_status
.exit_timestamp
.monotonic
,
969 (uint32_t) c
->exec_status
.pid
,
970 (int32_t) c
->exec_status
.code
,
971 (int32_t) c
->exec_status
.status
);
975 return sd_bus_message_close_container(reply
);
978 int bus_property_get_exec_command(
981 const char *interface
,
982 const char *property
,
983 sd_bus_message
*reply
,
985 sd_bus_error
*ret_error
) {
987 ExecCommand
*c
= (ExecCommand
*) userdata
;
993 r
= sd_bus_message_open_container(reply
, 'a', "(sasbttttuii)");
997 r
= append_exec_command(reply
, c
);
1001 return sd_bus_message_close_container(reply
);
1004 int bus_property_get_exec_command_list(
1007 const char *interface
,
1008 const char *property
,
1009 sd_bus_message
*reply
,
1011 sd_bus_error
*ret_error
) {
1013 ExecCommand
*c
= *(ExecCommand
**) userdata
;
1019 r
= sd_bus_message_open_container(reply
, 'a', "(sasbttttuii)");
1023 LIST_FOREACH(command
, c
, c
) {
1024 r
= append_exec_command(reply
, c
);
1029 return sd_bus_message_close_container(reply
);
1032 int bus_exec_context_set_transient_property(
1036 sd_bus_message
*message
,
1037 UnitSetPropertiesMode mode
,
1038 sd_bus_error
*error
) {
1040 const char *soft
= NULL
;
1048 if (streq(name
, "User")) {
1051 r
= sd_bus_message_read(message
, "s", &uu
);
1055 if (!isempty(uu
) && !valid_user_group_name_or_id(uu
))
1056 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid user name: %s", uu
);
1058 if (mode
!= UNIT_CHECK
) {
1061 c
->user
= mfree(c
->user
);
1062 else if (free_and_strdup(&c
->user
, uu
) < 0)
1065 unit_write_drop_in_private_format(u
, mode
, name
, "User=%s", uu
);
1070 } else if (streq(name
, "Group")) {
1073 r
= sd_bus_message_read(message
, "s", &gg
);
1077 if (!isempty(gg
) && !valid_user_group_name_or_id(gg
))
1078 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid group name: %s", gg
);
1080 if (mode
!= UNIT_CHECK
) {
1083 c
->group
= mfree(c
->group
);
1084 else if (free_and_strdup(&c
->group
, gg
) < 0)
1087 unit_write_drop_in_private_format(u
, mode
, name
, "Group=%s", gg
);
1092 } else if (streq(name
, "SupplementaryGroups")) {
1093 _cleanup_strv_free_
char **l
= NULL
;
1096 r
= sd_bus_message_read_strv(message
, &l
);
1100 STRV_FOREACH(p
, l
) {
1101 if (!isempty(*p
) && !valid_user_group_name_or_id(*p
))
1102 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid supplementary group names");
1105 if (mode
!= UNIT_CHECK
) {
1106 if (strv_length(l
) == 0) {
1107 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
1108 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
1110 _cleanup_free_
char *joined
= NULL
;
1112 r
= strv_extend_strv(&c
->supplementary_groups
, l
, true);
1116 joined
= strv_join(c
->supplementary_groups
, " ");
1120 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
1126 } else if (streq(name
, "SyslogIdentifier")) {
1129 r
= sd_bus_message_read(message
, "s", &id
);
1133 if (mode
!= UNIT_CHECK
) {
1136 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
1137 else if (free_and_strdup(&c
->syslog_identifier
, id
) < 0)
1140 unit_write_drop_in_private_format(u
, mode
, name
, "SyslogIdentifier=%s", id
);
1144 } else if (streq(name
, "SyslogLevel")) {
1147 r
= sd_bus_message_read(message
, "i", &level
);
1151 if (!log_level_is_valid(level
))
1152 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Log level value out of range");
1154 if (mode
!= UNIT_CHECK
) {
1155 c
->syslog_priority
= (c
->syslog_priority
& LOG_FACMASK
) | level
;
1156 unit_write_drop_in_private_format(u
, mode
, name
, "SyslogLevel=%i", level
);
1160 } else if (streq(name
, "SyslogFacility")) {
1163 r
= sd_bus_message_read(message
, "i", &facility
);
1167 if (!log_facility_unshifted_is_valid(facility
))
1168 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Log facility value out of range");
1170 if (mode
!= UNIT_CHECK
) {
1171 c
->syslog_priority
= (facility
<< 3) | LOG_PRI(c
->syslog_priority
);
1172 unit_write_drop_in_private_format(u
, mode
, name
, "SyslogFacility=%i", facility
);
1177 } else if (streq(name
, "LogLevelMax")) {
1180 r
= sd_bus_message_read(message
, "i", &level
);
1184 if (!log_level_is_valid(level
))
1185 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Maximum log level value out of range");
1187 if (mode
!= UNIT_CHECK
) {
1188 c
->log_level_max
= level
;
1189 unit_write_drop_in_private_format(u
, mode
, name
, "LogLevelMax=%i", level
);
1194 } else if (streq(name
, "LogExtraFields")) {
1197 r
= sd_bus_message_enter_container(message
, 'a', "ay");
1202 _cleanup_free_
void *copy
= NULL
;
1208 /* Note that we expect a byte array for each field, instead of a string. That's because on the
1209 * lower-level journal fields can actually contain binary data and are not restricted to text,
1210 * and we should not "lose precision" in our types on the way. That said, I am pretty sure
1211 * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
1212 * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
1213 * limitation, should a good, valid usecase arise. */
1215 r
= sd_bus_message_read_array(message
, 'y', &p
, &sz
);
1221 if (memchr(p
, 0, sz
))
1222 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field contains zero byte");
1224 eq
= memchr(p
, '=', sz
);
1226 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field contains no '=' character");
1227 if (!journal_field_valid(p
, eq
- (const char*) p
, false))
1228 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field invalid");
1230 if (mode
!= UNIT_CHECK
) {
1231 t
= realloc_multiply(c
->log_extra_fields
, sizeof(struct iovec
), c
->n_log_extra_fields
+1);
1234 c
->log_extra_fields
= t
;
1237 copy
= malloc(sz
+ 1);
1241 memcpy(copy
, p
, sz
);
1242 ((uint8_t*) copy
)[sz
] = 0;
1244 if (!utf8_is_valid(copy
))
1245 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field is not valid UTF-8");
1247 if (mode
!= UNIT_CHECK
) {
1248 c
->log_extra_fields
[c
->n_log_extra_fields
++] = IOVEC_MAKE(copy
, sz
);
1249 unit_write_drop_in_private_format(u
, mode
, name
, "LogExtraFields=%s", (char*) copy
);
1257 r
= sd_bus_message_exit_container(message
);
1261 if (mode
!= UNIT_CHECK
&& n
== 0) {
1262 exec_context_free_log_extra_fields(c
);
1263 unit_write_drop_in_private(u
, mode
, name
, "LogExtraFields=");
1268 } else if (streq(name
, "SecureBits")) {
1271 r
= sd_bus_message_read(message
, "i", &n
);
1275 if (!secure_bits_is_valid(n
))
1276 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid secure bits");
1278 if (mode
!= UNIT_CHECK
) {
1279 _cleanup_free_
char *str
= NULL
;
1282 r
= secure_bits_to_string_alloc(n
, &str
);
1286 unit_write_drop_in_private_format(u
, mode
, name
, "SecureBits=%s", str
);
1290 } else if (STR_IN_SET(name
, "CapabilityBoundingSet", "AmbientCapabilities")) {
1293 r
= sd_bus_message_read(message
, "t", &n
);
1297 if (mode
!= UNIT_CHECK
) {
1298 _cleanup_free_
char *str
= NULL
;
1300 if (streq(name
, "CapabilityBoundingSet"))
1301 c
->capability_bounding_set
= n
;
1302 else /* "AmbientCapabilities" */
1303 c
->capability_ambient_set
= n
;
1305 r
= capability_set_to_string_alloc(n
, &str
);
1309 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, str
);
1314 } else if (streq(name
, "Personality")) {
1318 r
= sd_bus_message_read(message
, "s", &s
);
1322 p
= personality_from_string(s
);
1323 if (p
== PERSONALITY_INVALID
)
1324 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid personality");
1326 if (mode
!= UNIT_CHECK
) {
1328 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
1335 } else if (streq(name
, "SystemCallFilter")) {
1337 _cleanup_strv_free_
char **l
= NULL
;
1339 r
= sd_bus_message_enter_container(message
, 'r', "bas");
1343 r
= sd_bus_message_read(message
, "b", &whitelist
);
1347 r
= sd_bus_message_read_strv(message
, &l
);
1351 r
= sd_bus_message_exit_container(message
);
1355 if (mode
!= UNIT_CHECK
) {
1356 _cleanup_free_
char *joined
= NULL
;
1358 if (strv_length(l
) == 0) {
1359 c
->syscall_whitelist
= false;
1360 c
->syscall_filter
= hashmap_free(c
->syscall_filter
);
1364 c
->syscall_whitelist
= whitelist
;
1366 r
= hashmap_ensure_allocated(&c
->syscall_filter
, NULL
);
1370 STRV_FOREACH(s
, l
) {
1371 _cleanup_free_
char *n
= NULL
;
1374 r
= parse_syscall_and_errno(*s
, &n
, &e
);
1379 const SyscallFilterSet
*set
;
1382 set
= syscall_filter_set_find(n
);
1386 NULSTR_FOREACH(i
, set
->value
) {
1389 id
= seccomp_syscall_resolve_name(i
);
1390 if (id
== __NR_SCMP_ERROR
)
1393 r
= hashmap_put(c
->syscall_filter
, INT_TO_PTR(id
+ 1), INT_TO_PTR(e
));
1401 id
= seccomp_syscall_resolve_name(n
);
1402 if (id
== __NR_SCMP_ERROR
)
1405 r
= hashmap_put(c
->syscall_filter
, INT_TO_PTR(id
+ 1), INT_TO_PTR(e
));
1412 joined
= strv_join(l
, " ");
1416 unit_write_drop_in_private_format(u
, mode
, name
, "SystemCallFilter=%s%s", whitelist
? "" : "~", joined
);
1421 } else if (streq(name
, "SystemCallArchitectures")) {
1422 _cleanup_strv_free_
char **l
= NULL
;
1424 r
= sd_bus_message_read_strv(message
, &l
);
1428 if (mode
!= UNIT_CHECK
) {
1429 _cleanup_free_
char *joined
= NULL
;
1431 if (strv_length(l
) == 0)
1432 c
->syscall_archs
= set_free(c
->syscall_archs
);
1436 r
= set_ensure_allocated(&c
->syscall_archs
, NULL
);
1440 STRV_FOREACH(s
, l
) {
1443 r
= seccomp_arch_from_string(*s
, &a
);
1447 r
= set_put(c
->syscall_archs
, UINT32_TO_PTR(a
+ 1));
1454 joined
= strv_join(l
, " ");
1458 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
1463 } else if (streq(name
, "SystemCallErrorNumber")) {
1466 r
= sd_bus_message_read(message
, "i", &n
);
1470 if (n
<= 0 || n
> ERRNO_MAX
)
1471 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SystemCallErrorNumber");
1473 if (mode
!= UNIT_CHECK
) {
1474 c
->syscall_errno
= n
;
1476 unit_write_drop_in_private_format(u
, mode
, name
, "SystemCallErrorNumber=%d", n
);
1481 } else if (streq(name
, "RestrictAddressFamilies")) {
1483 _cleanup_strv_free_
char **l
= NULL
;
1485 r
= sd_bus_message_enter_container(message
, 'r', "bas");
1489 r
= sd_bus_message_read(message
, "b", &whitelist
);
1493 r
= sd_bus_message_read_strv(message
, &l
);
1497 r
= sd_bus_message_exit_container(message
);
1501 if (mode
!= UNIT_CHECK
) {
1502 _cleanup_free_
char *joined
= NULL
;
1504 if (strv_length(l
) == 0) {
1505 c
->address_families_whitelist
= false;
1506 c
->address_families
= set_free(c
->address_families
);
1510 c
->address_families_whitelist
= whitelist
;
1512 r
= set_ensure_allocated(&c
->address_families
, NULL
);
1516 STRV_FOREACH(s
, l
) {
1519 af
= af_from_name(*s
);
1523 r
= set_put(c
->address_families
, INT_TO_PTR(af
));
1529 joined
= strv_join(l
, " ");
1533 unit_write_drop_in_private_format(u
, mode
, name
, "RestrictAddressFamilies=%s%s", whitelist
? "" : "~", joined
);
1539 } else if (streq(name
, "CPUSchedulingPolicy")) {
1542 r
= sd_bus_message_read(message
, "i", &n
);
1546 if (!sched_policy_is_valid(n
))
1547 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid CPU scheduling policy");
1549 if (mode
!= UNIT_CHECK
) {
1550 _cleanup_free_
char *str
= NULL
;
1552 c
->cpu_sched_policy
= n
;
1553 r
= sched_policy_to_string_alloc(n
, &str
);
1557 unit_write_drop_in_private_format(u
, mode
, name
, "CPUSchedulingPolicy=%s", str
);
1562 } else if (streq(name
, "CPUSchedulingPriority")) {
1565 r
= sd_bus_message_read(message
, "i", &n
);
1569 if (!ioprio_priority_is_valid(n
))
1570 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid CPU scheduling priority");
1572 if (mode
!= UNIT_CHECK
) {
1573 c
->cpu_sched_priority
= n
;
1574 unit_write_drop_in_private_format(u
, mode
, name
, "CPUSchedulingPriority=%i", n
);
1579 } else if (streq(name
, "CPUAffinity")) {
1583 r
= sd_bus_message_read_array(message
, 'y', &a
, &n
);
1587 if (mode
!= UNIT_CHECK
) {
1589 c
->cpuset
= mfree(c
->cpuset
);
1590 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
1592 _cleanup_free_
char *str
= NULL
;
1594 size_t allocated
= 0, len
= 0, i
;
1596 c
->cpuset
= (cpu_set_t
*) memdup(a
, sizeof(cpu_set_t
) * n
);
1601 for (i
= 0; i
< n
; i
++) {
1602 _cleanup_free_
char *p
= NULL
;
1605 r
= asprintf(&p
, "%hhi", l
[i
]);
1611 if (GREEDY_REALLOC(str
, allocated
, len
+ add
+ 2))
1614 strcpy(mempcpy(str
+ len
, p
, add
), " ");
1619 str
[len
- 1] = '\0';
1621 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, str
);
1626 } else if (streq(name
, "Nice")) {
1629 r
= sd_bus_message_read(message
, "i", &n
);
1633 if (!nice_is_valid(n
))
1634 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Nice value out of range");
1636 if (mode
!= UNIT_CHECK
) {
1638 unit_write_drop_in_private_format(u
, mode
, name
, "Nice=%i", n
);
1643 } else if (streq(name
, "IOSchedulingClass")) {
1646 r
= sd_bus_message_read(message
, "i", &q
);
1650 if (!ioprio_class_is_valid(q
))
1651 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid IO scheduling class: %i", q
);
1653 if (mode
!= UNIT_CHECK
) {
1654 _cleanup_free_
char *s
= NULL
;
1656 r
= ioprio_class_to_string_alloc(q
, &s
);
1660 c
->ioprio
= IOPRIO_PRIO_VALUE(q
, IOPRIO_PRIO_DATA(c
->ioprio
));
1661 c
->ioprio_set
= true;
1663 unit_write_drop_in_private_format(u
, mode
, name
, "IOSchedulingClass=%s", s
);
1668 } else if (streq(name
, "IOSchedulingPriority")) {
1671 r
= sd_bus_message_read(message
, "i", &p
);
1675 if (!ioprio_priority_is_valid(p
))
1676 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid IO scheduling priority: %i", p
);
1678 if (mode
!= UNIT_CHECK
) {
1679 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c
->ioprio
), p
);
1680 c
->ioprio_set
= true;
1682 unit_write_drop_in_private_format(u
, mode
, name
, "IOSchedulingPriority=%i", p
);
1687 } else if (STR_IN_SET(name
, "TTYPath", "RootDirectory", "RootImage")) {
1690 r
= sd_bus_message_read(message
, "s", &s
);
1694 if (!path_is_absolute(s
))
1695 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s takes an absolute path", name
);
1697 if (mode
!= UNIT_CHECK
) {
1698 if (streq(name
, "TTYPath"))
1699 r
= free_and_strdup(&c
->tty_path
, s
);
1700 else if (streq(name
, "RootImage"))
1701 r
= free_and_strdup(&c
->root_image
, s
);
1703 assert(streq(name
, "RootDirectory"));
1704 r
= free_and_strdup(&c
->root_directory
, s
);
1709 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
1714 } else if (streq(name
, "WorkingDirectory")) {
1718 r
= sd_bus_message_read(message
, "s", &s
);
1728 if (!streq(s
, "~") && !path_is_absolute(s
))
1729 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "WorkingDirectory= expects an absolute path or '~'");
1731 if (mode
!= UNIT_CHECK
) {
1732 if (streq(s
, "~")) {
1733 c
->working_directory
= mfree(c
->working_directory
);
1734 c
->working_directory_home
= true;
1736 r
= free_and_strdup(&c
->working_directory
, s
);
1740 c
->working_directory_home
= false;
1743 c
->working_directory_missing_ok
= missing_ok
;
1744 unit_write_drop_in_private_format(u
, mode
, name
, "WorkingDirectory=%s%s", missing_ok
? "-" : "", s
);
1749 } else if (streq(name
, "StandardInput")) {
1753 r
= sd_bus_message_read(message
, "s", &s
);
1757 p
= exec_input_from_string(s
);
1759 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard input name");
1761 if (mode
!= UNIT_CHECK
) {
1764 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInput=%s", exec_input_to_string(p
));
1769 } else if (streq(name
, "StandardOutput")) {
1773 r
= sd_bus_message_read(message
, "s", &s
);
1777 p
= exec_output_from_string(s
);
1779 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard output name");
1781 if (mode
!= UNIT_CHECK
) {
1784 unit_write_drop_in_private_format(u
, mode
, name
, "StandardOutput=%s", exec_output_to_string(p
));
1789 } else if (streq(name
, "StandardError")) {
1793 r
= sd_bus_message_read(message
, "s", &s
);
1797 p
= exec_output_from_string(s
);
1799 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard error name");
1801 if (mode
!= UNIT_CHECK
) {
1804 unit_write_drop_in_private_format(u
, mode
, name
, "StandardError=%s", exec_output_to_string(p
));
1809 } else if (STR_IN_SET(name
,
1810 "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
1813 r
= sd_bus_message_read(message
, "s", &s
);
1817 if (!fdname_is_valid(s
))
1818 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid file descriptor name");
1820 if (mode
!= UNIT_CHECK
) {
1821 if (streq(name
, "StandardInputFileDescriptorName")) {
1822 c
->std_input
= EXEC_INPUT_NAMED_FD
;
1823 r
= free_and_strdup(&c
->stdio_fdname
[STDIN_FILENO
], s
);
1826 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInput=fd:%s", s
);
1827 } else if (streq(name
, "StandardOutputFileDescriptorName")) {
1828 c
->std_output
= EXEC_OUTPUT_NAMED_FD
;
1829 r
= free_and_strdup(&c
->stdio_fdname
[STDOUT_FILENO
], s
);
1832 unit_write_drop_in_private_format(u
, mode
, name
, "StandardOutput=fd:%s", s
);
1833 } else if (streq(name
, "StandardErrorFileDescriptorName")) {
1834 c
->std_error
= EXEC_OUTPUT_NAMED_FD
;
1835 r
= free_and_strdup(&c
->stdio_fdname
[STDERR_FILENO
], s
);
1838 unit_write_drop_in_private_format(u
, mode
, name
, "StandardError=fd:%s", s
);
1844 } else if (STR_IN_SET(name
,
1845 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
1846 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
1847 "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
1848 "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
1849 "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
1850 "CPUSchedulingResetOnFork", "NonBlocking", "LockPersonality")) {
1853 r
= sd_bus_message_read(message
, "b", &b
);
1857 if (mode
!= UNIT_CHECK
) {
1858 if (streq(name
, "IgnoreSIGPIPE"))
1859 c
->ignore_sigpipe
= b
;
1860 else if (streq(name
, "TTYVHangup"))
1862 else if (streq(name
, "TTYReset"))
1864 else if (streq(name
, "TTYVTDisallocate"))
1865 c
->tty_vt_disallocate
= b
;
1866 else if (streq(name
, "PrivateTmp"))
1868 else if (streq(name
, "PrivateDevices"))
1869 c
->private_devices
= b
;
1870 else if (streq(name
, "PrivateNetwork"))
1871 c
->private_network
= b
;
1872 else if (streq(name
, "PrivateUsers"))
1873 c
->private_users
= b
;
1874 else if (streq(name
, "NoNewPrivileges"))
1875 c
->no_new_privileges
= b
;
1876 else if (streq(name
, "SyslogLevelPrefix"))
1877 c
->syslog_level_prefix
= b
;
1878 else if (streq(name
, "MemoryDenyWriteExecute"))
1879 c
->memory_deny_write_execute
= b
;
1880 else if (streq(name
, "RestrictRealtime"))
1881 c
->restrict_realtime
= b
;
1882 else if (streq(name
, "DynamicUser"))
1883 c
->dynamic_user
= b
;
1884 else if (streq(name
, "RemoveIPC"))
1886 else if (streq(name
, "ProtectKernelTunables"))
1887 c
->protect_kernel_tunables
= b
;
1888 else if (streq(name
, "ProtectKernelModules"))
1889 c
->protect_kernel_modules
= b
;
1890 else if (streq(name
, "ProtectControlGroups"))
1891 c
->protect_control_groups
= b
;
1892 else if (streq(name
, "MountAPIVFS"))
1893 c
->mount_apivfs
= b
;
1894 else if (streq(name
, "CPUSchedulingResetOnFork"))
1895 c
->cpu_sched_reset_on_fork
= b
;
1896 else if (streq(name
, "NonBlocking"))
1897 c
->non_blocking
= b
;
1898 else if (streq(name
, "LockPersonality"))
1899 c
->lock_personality
= b
;
1901 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, yes_no(b
));
1906 } else if (streq(name
, "UtmpIdentifier")) {
1909 r
= sd_bus_message_read(message
, "s", &id
);
1913 if (mode
!= UNIT_CHECK
) {
1915 c
->utmp_id
= mfree(c
->utmp_id
);
1916 else if (free_and_strdup(&c
->utmp_id
, id
) < 0)
1919 unit_write_drop_in_private_format(u
, mode
, name
, "UtmpIdentifier=%s", strempty(id
));
1924 } else if (streq(name
, "UtmpMode")) {
1928 r
= sd_bus_message_read(message
, "s", &s
);
1932 m
= exec_utmp_mode_from_string(s
);
1934 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid utmp mode");
1936 if (mode
!= UNIT_CHECK
) {
1939 unit_write_drop_in_private_format(u
, mode
, name
, "UtmpMode=%s", exec_utmp_mode_to_string(m
));
1944 } else if (streq(name
, "PAMName")) {
1947 r
= sd_bus_message_read(message
, "s", &n
);
1951 if (mode
!= UNIT_CHECK
) {
1953 c
->pam_name
= mfree(c
->pam_name
);
1954 else if (free_and_strdup(&c
->pam_name
, n
) < 0)
1957 unit_write_drop_in_private_format(u
, mode
, name
, "PAMName=%s", strempty(n
));
1962 } else if (streq(name
, "Environment")) {
1964 _cleanup_strv_free_
char **l
= NULL
, **q
= NULL
;
1966 r
= sd_bus_message_read_strv(message
, &l
);
1970 r
= unit_full_printf_strv(u
, l
, &q
);
1974 if (!strv_env_is_valid(q
))
1975 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment block.");
1977 if (mode
!= UNIT_CHECK
) {
1978 if (strv_length(q
) == 0) {
1979 c
->environment
= strv_free(c
->environment
);
1980 unit_write_drop_in_private_format(u
, mode
, name
, "Environment=");
1982 _cleanup_free_
char *joined
= NULL
;
1985 e
= strv_env_merge(2, c
->environment
, q
);
1989 strv_free(c
->environment
);
1992 /* We write just the new settings out to file, with unresolved specifiers */
1993 joined
= strv_join_quoted(l
);
1997 unit_write_drop_in_private_format(u
, mode
, name
, "Environment=%s", joined
);
2003 } else if (streq(name
, "UnsetEnvironment")) {
2005 _cleanup_strv_free_
char **l
= NULL
, **q
= NULL
;
2007 r
= sd_bus_message_read_strv(message
, &l
);
2011 r
= unit_full_printf_strv(u
, l
, &q
);
2015 if (!strv_env_name_or_assignment_is_valid(q
))
2016 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid UnsetEnvironment= list.");
2018 if (mode
!= UNIT_CHECK
) {
2019 if (strv_length(q
) == 0) {
2020 c
->unset_environment
= strv_free(c
->unset_environment
);
2021 unit_write_drop_in_private_format(u
, mode
, name
, "UnsetEnvironment=");
2023 _cleanup_free_
char *joined
= NULL
;
2026 e
= strv_env_merge(2, c
->unset_environment
, q
);
2030 strv_free(c
->unset_environment
);
2031 c
->unset_environment
= e
;
2033 /* We write just the new settings out to file, with unresolved specifiers */
2034 joined
= strv_join_quoted(l
);
2038 unit_write_drop_in_private_format(u
, mode
, name
, "UnsetEnvironment=%s", joined
);
2044 } else if (streq(name
, "TimerSlackNSec")) {
2048 r
= sd_bus_message_read(message
, "t", &n
);
2052 if (mode
!= UNIT_CHECK
) {
2053 c
->timer_slack_nsec
= n
;
2054 unit_write_drop_in_private_format(u
, mode
, name
, "TimerSlackNSec=" NSEC_FMT
, n
);
2059 } else if (streq(name
, "OOMScoreAdjust")) {
2062 r
= sd_bus_message_read(message
, "i", &oa
);
2066 if (!oom_score_adjust_is_valid(oa
))
2067 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "OOM score adjust value out of range");
2069 if (mode
!= UNIT_CHECK
) {
2070 c
->oom_score_adjust
= oa
;
2071 c
->oom_score_adjust_set
= true;
2072 unit_write_drop_in_private_format(u
, mode
, name
, "OOMScoreAdjust=%i", oa
);
2077 } else if (streq(name
, "EnvironmentFiles")) {
2079 _cleanup_free_
char *joined
= NULL
;
2080 _cleanup_fclose_
FILE *f
= NULL
;
2081 _cleanup_strv_free_
char **l
= NULL
;
2085 r
= sd_bus_message_enter_container(message
, 'a', "(sb)");
2089 f
= open_memstream(&joined
, &size
);
2093 STRV_FOREACH(i
, c
->environment_files
)
2094 fprintf(f
, "EnvironmentFile=%s", *i
);
2096 while ((r
= sd_bus_message_enter_container(message
, 'r', "sb")) > 0) {
2100 r
= sd_bus_message_read(message
, "sb", &path
, &b
);
2104 r
= sd_bus_message_exit_container(message
);
2108 if (!path_is_absolute(path
))
2109 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path %s is not absolute.", path
);
2111 if (mode
!= UNIT_CHECK
) {
2114 buf
= strjoin(b
? "-" : "", path
);
2118 fprintf(f
, "EnvironmentFile=%s", buf
);
2120 r
= strv_consume(&l
, buf
);
2128 r
= sd_bus_message_exit_container(message
);
2132 r
= fflush_and_check(f
);
2136 if (mode
!= UNIT_CHECK
) {
2137 if (strv_isempty(l
)) {
2138 c
->environment_files
= strv_free(c
->environment_files
);
2139 unit_write_drop_in_private(u
, mode
, name
, "EnvironmentFile=");
2141 r
= strv_extend_strv(&c
->environment_files
, l
, true);
2145 unit_write_drop_in_private(u
, mode
, name
, joined
);
2151 } else if (streq(name
, "PassEnvironment")) {
2153 _cleanup_strv_free_
char **l
= NULL
, **q
= NULL
;
2155 r
= sd_bus_message_read_strv(message
, &l
);
2159 r
= unit_full_printf_strv(u
, l
, &q
);
2163 if (!strv_env_name_is_valid(q
))
2164 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid PassEnvironment= block.");
2166 if (mode
!= UNIT_CHECK
) {
2167 if (strv_isempty(l
)) {
2168 c
->pass_environment
= strv_free(c
->pass_environment
);
2169 unit_write_drop_in_private_format(u
, mode
, name
, "PassEnvironment=");
2171 _cleanup_free_
char *joined
= NULL
;
2173 r
= strv_extend_strv(&c
->pass_environment
, q
, true);
2177 /* We write just the new settings out to file, with unresolved specifiers. */
2178 joined
= strv_join_quoted(l
);
2182 unit_write_drop_in_private_format(u
, mode
, name
, "PassEnvironment=%s", joined
);
2188 } else if (STR_IN_SET(name
, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
2189 "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
2190 _cleanup_strv_free_
char **l
= NULL
;
2194 r
= sd_bus_message_read_strv(message
, &l
);
2198 STRV_FOREACH(p
, l
) {
2202 if (!utf8_is_valid(i
))
2203 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid %s", name
);
2205 offset
= i
[0] == '-';
2206 offset
+= i
[offset
] == '+';
2207 if (!path_is_absolute(i
+ offset
))
2208 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid %s", name
);
2211 if (mode
!= UNIT_CHECK
) {
2212 _cleanup_free_
char *joined
= NULL
;
2214 if (STR_IN_SET(name
, "ReadWriteDirectories", "ReadWritePaths"))
2215 dirs
= &c
->read_write_paths
;
2216 else if (STR_IN_SET(name
, "ReadOnlyDirectories", "ReadOnlyPaths"))
2217 dirs
= &c
->read_only_paths
;
2218 else /* "InaccessiblePaths" */
2219 dirs
= &c
->inaccessible_paths
;
2221 if (strv_length(l
) == 0) {
2222 *dirs
= strv_free(*dirs
);
2223 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
2225 r
= strv_extend_strv(dirs
, l
, true);
2229 joined
= strv_join_quoted(*dirs
);
2233 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
2240 } else if (streq(name
, "ProtectSystem")) {
2244 r
= sd_bus_message_read(message
, "s", &s
);
2248 r
= parse_boolean(s
);
2250 ps
= PROTECT_SYSTEM_YES
;
2252 ps
= PROTECT_SYSTEM_NO
;
2254 ps
= protect_system_from_string(s
);
2256 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Failed to parse protect system value");
2259 if (mode
!= UNIT_CHECK
) {
2260 c
->protect_system
= ps
;
2261 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
2266 } else if (streq(name
, "ProtectHome")) {
2270 r
= sd_bus_message_read(message
, "s", &s
);
2274 r
= parse_boolean(s
);
2276 ph
= PROTECT_HOME_YES
;
2278 ph
= PROTECT_HOME_NO
;
2280 ph
= protect_home_from_string(s
);
2282 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Failed to parse protect home value");
2285 if (mode
!= UNIT_CHECK
) {
2286 c
->protect_home
= ph
;
2287 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
2292 } else if (streq(name
, "KeyringMode")) {
2297 r
= sd_bus_message_read(message
, "s", &s
);
2301 m
= exec_keyring_mode_from_string(s
);
2303 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid keyring mode");
2305 if (mode
!= UNIT_CHECK
) {
2306 c
->keyring_mode
= m
;
2308 unit_write_drop_in_private_format(u
, mode
, name
, "KeyringMode=%s", exec_keyring_mode_to_string(m
));
2313 } else if (streq(name
, "RuntimeDirectoryPreserve")) {
2317 r
= sd_bus_message_read(message
, "s", &s
);
2321 m
= exec_preserve_mode_from_string(s
);
2323 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid preserve mode");
2325 if (mode
!= UNIT_CHECK
) {
2326 c
->runtime_directory_preserve_mode
= m
;
2328 unit_write_drop_in_private_format(u
, mode
, name
, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m
));
2333 } else if (STR_IN_SET(name
, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) {
2336 r
= sd_bus_message_read(message
, "u", &m
);
2340 if (mode
!= UNIT_CHECK
) {
2341 ExecDirectoryType i
;
2343 if (streq(name
, "UMask"))
2346 for (i
= 0; i
< _EXEC_DIRECTORY_TYPE_MAX
; i
++)
2347 if (startswith(name
, exec_directory_type_to_string(i
))) {
2348 c
->directories
[i
].mode
= m
;
2352 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%040o", name
, m
);
2357 } else if (STR_IN_SET(name
, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
2358 _cleanup_strv_free_
char **l
= NULL
;
2361 r
= sd_bus_message_read_strv(message
, &l
);
2365 STRV_FOREACH(p
, l
) {
2366 if (!path_is_safe(*p
) || path_is_absolute(*p
))
2367 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= path is not valid: %s", name
, *p
);
2370 if (mode
!= UNIT_CHECK
) {
2371 _cleanup_free_
char *joined
= NULL
;
2372 char ***dirs
= NULL
;
2373 ExecDirectoryType i
;
2375 for (i
= 0; i
< _EXEC_DIRECTORY_TYPE_MAX
; i
++)
2376 if (streq(name
, exec_directory_type_to_string(i
))) {
2377 dirs
= &c
->directories
[i
].paths
;
2383 if (strv_isempty(l
)) {
2384 *dirs
= strv_free(*dirs
);
2385 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
2387 r
= strv_extend_strv(dirs
, l
, true);
2391 joined
= strv_join_quoted(*dirs
);
2395 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
2401 } else if (streq(name
, "SELinuxContext")) {
2403 r
= sd_bus_message_read(message
, "s", &s
);
2407 if (mode
!= UNIT_CHECK
) {
2409 c
->selinux_context
= mfree(c
->selinux_context
);
2410 else if (free_and_strdup(&c
->selinux_context
, s
) < 0)
2413 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, strempty(s
));
2418 } else if (STR_IN_SET(name
, "AppArmorProfile", "SmackProcessLabel")) {
2422 r
= sd_bus_message_enter_container(message
, 'r', "bs");
2426 r
= sd_bus_message_read(message
, "bs", &ignore
, &s
);
2430 if (mode
!= UNIT_CHECK
) {
2434 if (streq(name
, "AppArmorProfile")) {
2435 p
= &c
->apparmor_profile
;
2436 b
= &c
->apparmor_profile_ignore
;
2437 } else { /* "SmackProcessLabel" */
2438 p
= &c
->smack_process_label
;
2439 b
= &c
->smack_process_label_ignore
;
2446 if (free_and_strdup(p
, s
) < 0)
2451 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s%s", name
, ignore
? "-" : "", strempty(s
));
2456 } else if (streq(name
, "RestrictNamespaces")) {
2459 r
= sd_bus_message_read(message
, "t", &flags
);
2462 if ((flags
& NAMESPACE_FLAGS_ALL
) != flags
)
2463 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown namespace types");
2465 if (mode
!= UNIT_CHECK
) {
2466 _cleanup_free_
char *s
= NULL
;
2468 r
= namespace_flag_to_string_many(flags
, &s
);
2472 c
->restrict_namespaces
= flags
;
2473 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
2477 } else if (streq(name
, "MountFlags")) {
2480 r
= sd_bus_message_read(message
, "t", &flags
);
2483 if (!IN_SET(flags
, 0, MS_SHARED
, MS_PRIVATE
, MS_SLAVE
))
2484 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown mount propagation flags");
2486 if (mode
!= UNIT_CHECK
) {
2487 c
->mount_flags
= flags
;
2489 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, mount_propagation_flags_to_string(flags
));
2493 } else if (STR_IN_SET(name
, "BindPaths", "BindReadOnlyPaths")) {
2494 unsigned empty
= true;
2496 r
= sd_bus_message_enter_container(message
, 'a', "(ssbt)");
2500 while ((r
= sd_bus_message_enter_container(message
, 'r', "ssbt")) > 0) {
2501 const char *source
, *destination
;
2503 uint64_t mount_flags
;
2505 r
= sd_bus_message_read(message
, "ssbt", &source
, &destination
, &ignore_enoent
, &mount_flags
);
2509 r
= sd_bus_message_exit_container(message
);
2513 if (!path_is_absolute(source
))
2514 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Source path %s is not absolute.", source
);
2515 if (!path_is_absolute(destination
))
2516 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Destination path %s is not absolute.", destination
);
2517 if (!IN_SET(mount_flags
, 0, MS_REC
))
2518 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown mount flags.");
2520 if (mode
!= UNIT_CHECK
) {
2521 r
= bind_mount_add(&c
->bind_mounts
, &c
->n_bind_mounts
,
2523 .source
= strdup(source
),
2524 .destination
= strdup(destination
),
2525 .read_only
= !!strstr(name
, "ReadOnly"),
2526 .recursive
= !!(mount_flags
& MS_REC
),
2527 .ignore_enoent
= ignore_enoent
,
2532 unit_write_drop_in_private_format(
2536 ignore_enoent
? "-" : "",
2539 (mount_flags
& MS_REC
) ? "rbind" : "norbind");
2547 r
= sd_bus_message_exit_container(message
);
2552 bind_mount_free_many(c
->bind_mounts
, c
->n_bind_mounts
);
2553 c
->bind_mounts
= NULL
;
2554 c
->n_bind_mounts
= 0;
2560 ri
= rlimit_from_string(name
);
2562 soft
= endswith(name
, "Soft");
2566 n
= strndupa(name
, soft
- name
);
2567 ri
= rlimit_from_string(n
);
2578 r
= sd_bus_message_read(message
, "t", &rl
);
2582 if (rl
== (uint64_t) -1)
2587 if ((uint64_t) x
!= rl
)
2591 if (mode
!= UNIT_CHECK
) {
2592 _cleanup_free_
char *f
= NULL
;
2595 if (c
->rlimit
[ri
]) {
2596 nl
= *c
->rlimit
[ri
];
2603 /* When the resource limit is not initialized yet, then assign the value to both fields */
2604 nl
= (struct rlimit
) {
2609 r
= rlimit_format(&nl
, &f
);
2614 *c
->rlimit
[ri
] = nl
;
2616 c
->rlimit
[ri
] = newdup(struct rlimit
, &nl
, 1);
2621 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, f
);