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"
38 #include "hexdecoct.h"
41 #include "journal-util.h"
43 #include "mount-util.h"
44 #include "namespace.h"
45 #include "parse-util.h"
46 #include "path-util.h"
47 #include "process-util.h"
48 #include "rlimit-util.h"
50 #include "seccomp-util.h"
52 #include "securebits-util.h"
54 #include "syslog-util.h"
55 #include "unit-printf.h"
56 #include "user-util.h"
59 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output
, exec_output
, ExecOutput
);
60 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input
, exec_input
, ExecInput
);
62 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode
, exec_utmp_mode
, ExecUtmpMode
);
63 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode
, exec_preserve_mode
, ExecPreserveMode
);
64 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode
, exec_keyring_mode
, ExecKeyringMode
);
66 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home
, protect_home
, ProtectHome
);
67 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system
, protect_system
, ProtectSystem
);
69 static int property_get_environment_files(
72 const char *interface
,
74 sd_bus_message
*reply
,
76 sd_bus_error
*error
) {
78 ExecContext
*c
= userdata
;
86 r
= sd_bus_message_open_container(reply
, 'a', "(sb)");
90 STRV_FOREACH(j
, c
->environment_files
) {
93 r
= sd_bus_message_append(reply
, "(sb)", fn
[0] == '-' ? fn
+ 1 : fn
, fn
[0] == '-');
98 return sd_bus_message_close_container(reply
);
101 static int property_get_oom_score_adjust(
104 const char *interface
,
105 const char *property
,
106 sd_bus_message
*reply
,
108 sd_bus_error
*error
) {
111 ExecContext
*c
= userdata
;
118 if (c
->oom_score_adjust_set
)
119 n
= c
->oom_score_adjust
;
121 _cleanup_free_
char *t
= NULL
;
124 if (read_one_line_file("/proc/self/oom_score_adj", &t
) >= 0)
128 return sd_bus_message_append(reply
, "i", n
);
131 static int property_get_nice(
134 const char *interface
,
135 const char *property
,
136 sd_bus_message
*reply
,
138 sd_bus_error
*error
) {
141 ExecContext
*c
= userdata
;
152 n
= getpriority(PRIO_PROCESS
, 0);
157 return sd_bus_message_append(reply
, "i", n
);
160 static int property_get_ioprio(
163 const char *interface
,
164 const char *property
,
165 sd_bus_message
*reply
,
167 sd_bus_error
*error
) {
170 ExecContext
*c
= userdata
;
176 return sd_bus_message_append(reply
, "i", exec_context_get_effective_ioprio(c
));
179 static int property_get_ioprio_class(
182 const char *interface
,
183 const char *property
,
184 sd_bus_message
*reply
,
186 sd_bus_error
*error
) {
189 ExecContext
*c
= userdata
;
195 return sd_bus_message_append(reply
, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c
)));
198 static int property_get_ioprio_priority(
201 const char *interface
,
202 const char *property
,
203 sd_bus_message
*reply
,
205 sd_bus_error
*error
) {
208 ExecContext
*c
= userdata
;
214 return sd_bus_message_append(reply
, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c
)));
217 static int property_get_cpu_sched_policy(
220 const char *interface
,
221 const char *property
,
222 sd_bus_message
*reply
,
224 sd_bus_error
*error
) {
226 ExecContext
*c
= userdata
;
233 if (c
->cpu_sched_set
)
234 n
= c
->cpu_sched_policy
;
236 n
= sched_getscheduler(0);
241 return sd_bus_message_append(reply
, "i", n
);
244 static int property_get_cpu_sched_priority(
247 const char *interface
,
248 const char *property
,
249 sd_bus_message
*reply
,
251 sd_bus_error
*error
) {
253 ExecContext
*c
= userdata
;
260 if (c
->cpu_sched_set
)
261 n
= c
->cpu_sched_priority
;
263 struct sched_param p
= {};
265 if (sched_getparam(0, &p
) >= 0)
266 n
= p
.sched_priority
;
271 return sd_bus_message_append(reply
, "i", n
);
274 static int property_get_cpu_affinity(
277 const char *interface
,
278 const char *property
,
279 sd_bus_message
*reply
,
281 sd_bus_error
*error
) {
283 ExecContext
*c
= userdata
;
290 return sd_bus_message_append_array(reply
, 'y', c
->cpuset
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
));
292 return sd_bus_message_append_array(reply
, 'y', NULL
, 0);
295 static int property_get_timer_slack_nsec(
298 const char *interface
,
299 const char *property
,
300 sd_bus_message
*reply
,
302 sd_bus_error
*error
) {
304 ExecContext
*c
= userdata
;
311 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
312 u
= (uint64_t) c
->timer_slack_nsec
;
314 u
= (uint64_t) prctl(PR_GET_TIMERSLACK
);
316 return sd_bus_message_append(reply
, "t", u
);
319 static int property_get_capability_bounding_set(
322 const char *interface
,
323 const char *property
,
324 sd_bus_message
*reply
,
326 sd_bus_error
*error
) {
328 ExecContext
*c
= userdata
;
334 return sd_bus_message_append(reply
, "t", c
->capability_bounding_set
);
337 static int property_get_ambient_capabilities(
340 const char *interface
,
341 const char *property
,
342 sd_bus_message
*reply
,
344 sd_bus_error
*error
) {
346 ExecContext
*c
= userdata
;
352 return sd_bus_message_append(reply
, "t", c
->capability_ambient_set
);
355 static int property_get_empty_string(
358 const char *interface
,
359 const char *property
,
360 sd_bus_message
*reply
,
362 sd_bus_error
*error
) {
367 return sd_bus_message_append(reply
, "s", "");
370 static int property_get_syscall_filter(
373 const char *interface
,
374 const char *property
,
375 sd_bus_message
*reply
,
377 sd_bus_error
*error
) {
379 ExecContext
*c
= userdata
;
380 _cleanup_strv_free_
char **l
= NULL
;
392 r
= sd_bus_message_open_container(reply
, 'r', "bas");
396 r
= sd_bus_message_append(reply
, "b", c
->syscall_whitelist
);
401 HASHMAP_FOREACH_KEY(val
, id
, c
->syscall_filter
, i
) {
402 _cleanup_free_
char *name
= NULL
;
403 const char *e
= NULL
;
405 int num
= PTR_TO_INT(val
);
407 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
412 e
= errno_to_name(num
);
414 s
= strjoin(name
, ":", e
);
418 r
= asprintf(&s
, "%s:%d", name
, num
);
427 r
= strv_consume(&l
, s
);
435 r
= sd_bus_message_append_strv(reply
, l
);
439 return sd_bus_message_close_container(reply
);
442 static int property_get_syscall_archs(
445 const char *interface
,
446 const char *property
,
447 sd_bus_message
*reply
,
449 sd_bus_error
*error
) {
451 ExecContext
*c
= userdata
;
452 _cleanup_strv_free_
char **l
= NULL
;
465 SET_FOREACH(id
, c
->syscall_archs
, i
) {
468 name
= seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1);
472 r
= strv_extend(&l
, name
);
480 r
= sd_bus_message_append_strv(reply
, l
);
487 static int property_get_syscall_errno(
490 const char *interface
,
491 const char *property
,
492 sd_bus_message
*reply
,
494 sd_bus_error
*error
) {
496 ExecContext
*c
= userdata
;
502 return sd_bus_message_append(reply
, "i", (int32_t) c
->syscall_errno
);
505 static int property_get_selinux_context(
508 const char *interface
,
509 const char *property
,
510 sd_bus_message
*reply
,
512 sd_bus_error
*error
) {
514 ExecContext
*c
= userdata
;
520 return sd_bus_message_append(reply
, "(bs)", c
->selinux_context_ignore
, c
->selinux_context
);
523 static int property_get_apparmor_profile(
526 const char *interface
,
527 const char *property
,
528 sd_bus_message
*reply
,
530 sd_bus_error
*error
) {
532 ExecContext
*c
= userdata
;
538 return sd_bus_message_append(reply
, "(bs)", c
->apparmor_profile_ignore
, c
->apparmor_profile
);
541 static int property_get_smack_process_label(
544 const char *interface
,
545 const char *property
,
546 sd_bus_message
*reply
,
548 sd_bus_error
*error
) {
550 ExecContext
*c
= userdata
;
556 return sd_bus_message_append(reply
, "(bs)", c
->smack_process_label_ignore
, c
->smack_process_label
);
559 static int property_get_personality(
562 const char *interface
,
563 const char *property
,
564 sd_bus_message
*reply
,
566 sd_bus_error
*error
) {
568 ExecContext
*c
= userdata
;
574 return sd_bus_message_append(reply
, "s", personality_to_string(c
->personality
));
577 static int property_get_address_families(
580 const char *interface
,
581 const char *property
,
582 sd_bus_message
*reply
,
584 sd_bus_error
*error
) {
586 ExecContext
*c
= userdata
;
587 _cleanup_strv_free_
char **l
= NULL
;
596 r
= sd_bus_message_open_container(reply
, 'r', "bas");
600 r
= sd_bus_message_append(reply
, "b", c
->address_families_whitelist
);
604 SET_FOREACH(af
, c
->address_families
, i
) {
607 name
= af_to_name(PTR_TO_INT(af
));
611 r
= strv_extend(&l
, name
);
618 r
= sd_bus_message_append_strv(reply
, l
);
622 return sd_bus_message_close_container(reply
);
625 static int property_get_working_directory(
628 const char *interface
,
629 const char *property
,
630 sd_bus_message
*reply
,
632 sd_bus_error
*error
) {
634 ExecContext
*c
= userdata
;
641 if (c
->working_directory_home
)
644 wd
= c
->working_directory
;
646 if (c
->working_directory_missing_ok
)
647 wd
= strjoina("!", wd
);
649 return sd_bus_message_append(reply
, "s", wd
);
652 static int property_get_syslog_level(
655 const char *interface
,
656 const char *property
,
657 sd_bus_message
*reply
,
659 sd_bus_error
*error
) {
661 ExecContext
*c
= userdata
;
667 return sd_bus_message_append(reply
, "i", LOG_PRI(c
->syslog_priority
));
670 static int property_get_syslog_facility(
673 const char *interface
,
674 const char *property
,
675 sd_bus_message
*reply
,
677 sd_bus_error
*error
) {
679 ExecContext
*c
= userdata
;
685 return sd_bus_message_append(reply
, "i", LOG_FAC(c
->syslog_priority
));
688 static int property_get_stdio_fdname(
691 const char *interface
,
692 const char *property
,
693 sd_bus_message
*reply
,
695 sd_bus_error
*error
) {
697 ExecContext
*c
= userdata
;
705 if (streq(property
, "StandardInputFileDescriptorName"))
706 fileno
= STDIN_FILENO
;
707 else if (streq(property
, "StandardOutputFileDescriptorName"))
708 fileno
= STDOUT_FILENO
;
710 assert(streq(property
, "StandardErrorFileDescriptorName"));
711 fileno
= STDERR_FILENO
;
714 return sd_bus_message_append(reply
, "s", exec_context_fdname(c
, fileno
));
717 static int property_get_input_data(
720 const char *interface
,
721 const char *property
,
722 sd_bus_message
*reply
,
724 sd_bus_error
*error
) {
726 ExecContext
*c
= userdata
;
733 return sd_bus_message_append_array(reply
, 'y', c
->stdin_data
, c
->stdin_data_size
);
736 static int property_get_bind_paths(
739 const char *interface
,
740 const char *property
,
741 sd_bus_message
*reply
,
743 sd_bus_error
*error
) {
745 ExecContext
*c
= userdata
;
755 ro
= !!strstr(property
, "ReadOnly");
757 r
= sd_bus_message_open_container(reply
, 'a', "(ssbt)");
761 for (i
= 0; i
< c
->n_bind_mounts
; i
++) {
763 if (ro
!= c
->bind_mounts
[i
].read_only
)
766 r
= sd_bus_message_append(
768 c
->bind_mounts
[i
].source
,
769 c
->bind_mounts
[i
].destination
,
770 c
->bind_mounts
[i
].ignore_enoent
,
771 c
->bind_mounts
[i
].recursive
? (uint64_t) MS_REC
: (uint64_t) 0);
776 return sd_bus_message_close_container(reply
);
779 static int property_get_log_extra_fields(
782 const char *interface
,
783 const char *property
,
784 sd_bus_message
*reply
,
786 sd_bus_error
*error
) {
788 ExecContext
*c
= userdata
;
797 r
= sd_bus_message_open_container(reply
, 'a', "ay");
801 for (i
= 0; i
< c
->n_log_extra_fields
; i
++) {
802 r
= sd_bus_message_append_array(reply
, 'y', c
->log_extra_fields
[i
].iov_base
, c
->log_extra_fields
[i
].iov_len
);
807 return sd_bus_message_close_container(reply
);
810 const sd_bus_vtable bus_exec_vtable
[] = {
811 SD_BUS_VTABLE_START(0),
812 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(ExecContext
, environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
813 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
814 SD_BUS_PROPERTY("PassEnvironment", "as", NULL
, offsetof(ExecContext
, pass_environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
815 SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL
, offsetof(ExecContext
, unset_environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
816 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode
, offsetof(ExecContext
, umask
), SD_BUS_VTABLE_PROPERTY_CONST
),
817 SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CPU
]), SD_BUS_VTABLE_PROPERTY_CONST
),
818 SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CPU
]), SD_BUS_VTABLE_PROPERTY_CONST
),
819 SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_FSIZE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
820 SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_FSIZE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
821 SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_DATA
]), SD_BUS_VTABLE_PROPERTY_CONST
),
822 SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_DATA
]), SD_BUS_VTABLE_PROPERTY_CONST
),
823 SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_STACK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
824 SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_STACK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
825 SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CORE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
826 SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CORE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
827 SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RSS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
828 SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RSS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
829 SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NOFILE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
830 SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NOFILE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
831 SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_AS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
832 SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_AS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
833 SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NPROC
]), SD_BUS_VTABLE_PROPERTY_CONST
),
834 SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NPROC
]), SD_BUS_VTABLE_PROPERTY_CONST
),
835 SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MEMLOCK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
836 SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MEMLOCK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
837 SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_LOCKS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
838 SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_LOCKS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
839 SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_SIGPENDING
]), SD_BUS_VTABLE_PROPERTY_CONST
),
840 SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_SIGPENDING
]), SD_BUS_VTABLE_PROPERTY_CONST
),
841 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MSGQUEUE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
842 SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MSGQUEUE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
843 SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NICE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
844 SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NICE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
845 SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTPRIO
]), SD_BUS_VTABLE_PROPERTY_CONST
),
846 SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTPRIO
]), SD_BUS_VTABLE_PROPERTY_CONST
),
847 SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTTIME
]), SD_BUS_VTABLE_PROPERTY_CONST
),
848 SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTTIME
]), SD_BUS_VTABLE_PROPERTY_CONST
),
849 SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
850 SD_BUS_PROPERTY("RootDirectory", "s", NULL
, offsetof(ExecContext
, root_directory
), SD_BUS_VTABLE_PROPERTY_CONST
),
851 SD_BUS_PROPERTY("RootImage", "s", NULL
, offsetof(ExecContext
, root_image
), SD_BUS_VTABLE_PROPERTY_CONST
),
852 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
853 SD_BUS_PROPERTY("Nice", "i", property_get_nice
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
854 SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
855 SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
856 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
857 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
858 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
859 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
860 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool
, offsetof(ExecContext
, cpu_sched_reset_on_fork
), SD_BUS_VTABLE_PROPERTY_CONST
),
861 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool
, offsetof(ExecContext
, non_blocking
), SD_BUS_VTABLE_PROPERTY_CONST
),
862 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input
, offsetof(ExecContext
, std_input
), SD_BUS_VTABLE_PROPERTY_CONST
),
863 SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
864 SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
865 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output
, offsetof(ExecContext
, std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
866 SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
867 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output
, offsetof(ExecContext
, std_error
), SD_BUS_VTABLE_PROPERTY_CONST
),
868 SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
869 SD_BUS_PROPERTY("TTYPath", "s", NULL
, offsetof(ExecContext
, tty_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
870 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_reset
), SD_BUS_VTABLE_PROPERTY_CONST
),
871 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_vhangup
), SD_BUS_VTABLE_PROPERTY_CONST
),
872 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_vt_disallocate
), SD_BUS_VTABLE_PROPERTY_CONST
),
873 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int
, offsetof(ExecContext
, syslog_priority
), SD_BUS_VTABLE_PROPERTY_CONST
),
874 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL
, offsetof(ExecContext
, syslog_identifier
), SD_BUS_VTABLE_PROPERTY_CONST
),
875 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool
, offsetof(ExecContext
, syslog_level_prefix
), SD_BUS_VTABLE_PROPERTY_CONST
),
876 SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
877 SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
878 SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int
, offsetof(ExecContext
, log_level_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
879 SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
880 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int
, offsetof(ExecContext
, secure_bits
), SD_BUS_VTABLE_PROPERTY_CONST
),
881 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
882 SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
883 SD_BUS_PROPERTY("User", "s", NULL
, offsetof(ExecContext
, user
), SD_BUS_VTABLE_PROPERTY_CONST
),
884 SD_BUS_PROPERTY("Group", "s", NULL
, offsetof(ExecContext
, group
), SD_BUS_VTABLE_PROPERTY_CONST
),
885 SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool
, offsetof(ExecContext
, dynamic_user
), SD_BUS_VTABLE_PROPERTY_CONST
),
886 SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool
, offsetof(ExecContext
, remove_ipc
), SD_BUS_VTABLE_PROPERTY_CONST
),
887 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL
, offsetof(ExecContext
, supplementary_groups
), SD_BUS_VTABLE_PROPERTY_CONST
),
888 SD_BUS_PROPERTY("PAMName", "s", NULL
, offsetof(ExecContext
, pam_name
), SD_BUS_VTABLE_PROPERTY_CONST
),
889 SD_BUS_PROPERTY("ReadWritePaths", "as", NULL
, offsetof(ExecContext
, read_write_paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
890 SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL
, offsetof(ExecContext
, read_only_paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
891 SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL
, offsetof(ExecContext
, inaccessible_paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
892 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong
, offsetof(ExecContext
, mount_flags
), SD_BUS_VTABLE_PROPERTY_CONST
),
893 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool
, offsetof(ExecContext
, private_tmp
), SD_BUS_VTABLE_PROPERTY_CONST
),
894 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool
, offsetof(ExecContext
, private_devices
), SD_BUS_VTABLE_PROPERTY_CONST
),
895 SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool
, offsetof(ExecContext
, protect_kernel_tunables
), SD_BUS_VTABLE_PROPERTY_CONST
),
896 SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool
, offsetof(ExecContext
, protect_kernel_modules
), SD_BUS_VTABLE_PROPERTY_CONST
),
897 SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool
, offsetof(ExecContext
, protect_control_groups
), SD_BUS_VTABLE_PROPERTY_CONST
),
898 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool
, offsetof(ExecContext
, private_network
), SD_BUS_VTABLE_PROPERTY_CONST
),
899 SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool
, offsetof(ExecContext
, private_users
), SD_BUS_VTABLE_PROPERTY_CONST
),
900 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home
, offsetof(ExecContext
, protect_home
), SD_BUS_VTABLE_PROPERTY_CONST
),
901 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system
, offsetof(ExecContext
, protect_system
), SD_BUS_VTABLE_PROPERTY_CONST
),
902 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool
, offsetof(ExecContext
, same_pgrp
), SD_BUS_VTABLE_PROPERTY_CONST
),
903 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL
, offsetof(ExecContext
, utmp_id
), SD_BUS_VTABLE_PROPERTY_CONST
),
904 SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode
, offsetof(ExecContext
, utmp_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
905 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
906 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
907 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
908 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool
, offsetof(ExecContext
, ignore_sigpipe
), SD_BUS_VTABLE_PROPERTY_CONST
),
909 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool
, offsetof(ExecContext
, no_new_privileges
), SD_BUS_VTABLE_PROPERTY_CONST
),
910 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
911 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
912 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
913 SD_BUS_PROPERTY("Personality", "s", property_get_personality
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
914 SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool
, offsetof(ExecContext
, lock_personality
), SD_BUS_VTABLE_PROPERTY_CONST
),
915 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
916 SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode
, offsetof(ExecContext
, runtime_directory_preserve_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
917 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_RUNTIME
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
918 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_RUNTIME
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
919 SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_STATE
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
920 SD_BUS_PROPERTY("StateDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_STATE
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
921 SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CACHE
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
922 SD_BUS_PROPERTY("CacheDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CACHE
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
923 SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_LOGS
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
924 SD_BUS_PROPERTY("LogsDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_LOGS
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
925 SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CONFIGURATION
].mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
926 SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL
, offsetof(ExecContext
, directories
[EXEC_DIRECTORY_CONFIGURATION
].paths
), SD_BUS_VTABLE_PROPERTY_CONST
),
927 SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool
, offsetof(ExecContext
, memory_deny_write_execute
), SD_BUS_VTABLE_PROPERTY_CONST
),
928 SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool
, offsetof(ExecContext
, restrict_realtime
), SD_BUS_VTABLE_PROPERTY_CONST
),
929 SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong
, offsetof(ExecContext
, restrict_namespaces
), SD_BUS_VTABLE_PROPERTY_CONST
),
930 SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
931 SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
932 SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool
, offsetof(ExecContext
, mount_apivfs
), SD_BUS_VTABLE_PROPERTY_CONST
),
933 SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode
, offsetof(ExecContext
, keyring_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
935 /* Obsolete/redundant properties: */
936 SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string
, 0, SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
937 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL
, offsetof(ExecContext
, read_write_paths
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
938 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL
, offsetof(ExecContext
, read_only_paths
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
939 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL
, offsetof(ExecContext
, inaccessible_paths
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
940 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio
, 0, SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
945 static int append_exec_command(sd_bus_message
*reply
, ExecCommand
*c
) {
954 r
= sd_bus_message_open_container(reply
, 'r', "sasbttttuii");
958 r
= sd_bus_message_append(reply
, "s", c
->path
);
962 r
= sd_bus_message_append_strv(reply
, c
->argv
);
966 r
= sd_bus_message_append(reply
, "bttttuii",
967 !!(c
->flags
& EXEC_COMMAND_IGNORE_FAILURE
),
968 c
->exec_status
.start_timestamp
.realtime
,
969 c
->exec_status
.start_timestamp
.monotonic
,
970 c
->exec_status
.exit_timestamp
.realtime
,
971 c
->exec_status
.exit_timestamp
.monotonic
,
972 (uint32_t) c
->exec_status
.pid
,
973 (int32_t) c
->exec_status
.code
,
974 (int32_t) c
->exec_status
.status
);
978 return sd_bus_message_close_container(reply
);
981 int bus_property_get_exec_command(
984 const char *interface
,
985 const char *property
,
986 sd_bus_message
*reply
,
988 sd_bus_error
*ret_error
) {
990 ExecCommand
*c
= (ExecCommand
*) userdata
;
996 r
= sd_bus_message_open_container(reply
, 'a', "(sasbttttuii)");
1000 r
= append_exec_command(reply
, c
);
1004 return sd_bus_message_close_container(reply
);
1007 int bus_property_get_exec_command_list(
1010 const char *interface
,
1011 const char *property
,
1012 sd_bus_message
*reply
,
1014 sd_bus_error
*ret_error
) {
1016 ExecCommand
*c
= *(ExecCommand
**) userdata
;
1022 r
= sd_bus_message_open_container(reply
, 'a', "(sasbttttuii)");
1026 LIST_FOREACH(command
, c
, c
) {
1027 r
= append_exec_command(reply
, c
);
1032 return sd_bus_message_close_container(reply
);
1035 int bus_exec_context_set_transient_property(
1039 sd_bus_message
*message
,
1040 UnitSetPropertiesMode mode
,
1041 sd_bus_error
*error
) {
1043 const char *soft
= NULL
;
1051 if (streq(name
, "User")) {
1054 r
= sd_bus_message_read(message
, "s", &uu
);
1058 if (!isempty(uu
) && !valid_user_group_name_or_id(uu
))
1059 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid user name: %s", uu
);
1061 if (mode
!= UNIT_CHECK
) {
1064 c
->user
= mfree(c
->user
);
1065 else if (free_and_strdup(&c
->user
, uu
) < 0)
1068 unit_write_drop_in_private_format(u
, mode
, name
, "User=%s", uu
);
1073 } else if (streq(name
, "Group")) {
1076 r
= sd_bus_message_read(message
, "s", &gg
);
1080 if (!isempty(gg
) && !valid_user_group_name_or_id(gg
))
1081 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid group name: %s", gg
);
1083 if (mode
!= UNIT_CHECK
) {
1086 c
->group
= mfree(c
->group
);
1087 else if (free_and_strdup(&c
->group
, gg
) < 0)
1090 unit_write_drop_in_private_format(u
, mode
, name
, "Group=%s", gg
);
1095 } else if (streq(name
, "SupplementaryGroups")) {
1096 _cleanup_strv_free_
char **l
= NULL
;
1099 r
= sd_bus_message_read_strv(message
, &l
);
1103 STRV_FOREACH(p
, l
) {
1104 if (!isempty(*p
) && !valid_user_group_name_or_id(*p
))
1105 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid supplementary group names");
1108 if (mode
!= UNIT_CHECK
) {
1109 if (strv_length(l
) == 0) {
1110 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
1111 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
1113 _cleanup_free_
char *joined
= NULL
;
1115 r
= strv_extend_strv(&c
->supplementary_groups
, l
, true);
1119 joined
= strv_join(c
->supplementary_groups
, " ");
1123 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
1129 } else if (streq(name
, "SyslogIdentifier")) {
1132 r
= sd_bus_message_read(message
, "s", &id
);
1136 if (mode
!= UNIT_CHECK
) {
1139 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
1140 else if (free_and_strdup(&c
->syslog_identifier
, id
) < 0)
1143 unit_write_drop_in_private_format(u
, mode
, name
, "SyslogIdentifier=%s", id
);
1147 } else if (streq(name
, "SyslogLevel")) {
1150 r
= sd_bus_message_read(message
, "i", &level
);
1154 if (!log_level_is_valid(level
))
1155 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Log level value out of range");
1157 if (mode
!= UNIT_CHECK
) {
1158 c
->syslog_priority
= (c
->syslog_priority
& LOG_FACMASK
) | level
;
1159 unit_write_drop_in_private_format(u
, mode
, name
, "SyslogLevel=%i", level
);
1163 } else if (streq(name
, "SyslogFacility")) {
1166 r
= sd_bus_message_read(message
, "i", &facility
);
1170 if (!log_facility_unshifted_is_valid(facility
))
1171 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Log facility value out of range");
1173 if (mode
!= UNIT_CHECK
) {
1174 c
->syslog_priority
= (facility
<< 3) | LOG_PRI(c
->syslog_priority
);
1175 unit_write_drop_in_private_format(u
, mode
, name
, "SyslogFacility=%i", facility
);
1180 } else if (streq(name
, "LogLevelMax")) {
1183 r
= sd_bus_message_read(message
, "i", &level
);
1187 if (!log_level_is_valid(level
))
1188 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Maximum log level value out of range");
1190 if (mode
!= UNIT_CHECK
) {
1191 c
->log_level_max
= level
;
1192 unit_write_drop_in_private_format(u
, mode
, name
, "LogLevelMax=%i", level
);
1197 } else if (streq(name
, "LogExtraFields")) {
1200 r
= sd_bus_message_enter_container(message
, 'a', "ay");
1205 _cleanup_free_
void *copy
= NULL
;
1211 /* Note that we expect a byte array for each field, instead of a string. That's because on the
1212 * lower-level journal fields can actually contain binary data and are not restricted to text,
1213 * and we should not "lose precision" in our types on the way. That said, I am pretty sure
1214 * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
1215 * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
1216 * limitation, should a good, valid usecase arise. */
1218 r
= sd_bus_message_read_array(message
, 'y', &p
, &sz
);
1224 if (memchr(p
, 0, sz
))
1225 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field contains zero byte");
1227 eq
= memchr(p
, '=', sz
);
1229 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field contains no '=' character");
1230 if (!journal_field_valid(p
, eq
- (const char*) p
, false))
1231 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field invalid");
1233 if (mode
!= UNIT_CHECK
) {
1234 t
= realloc_multiply(c
->log_extra_fields
, sizeof(struct iovec
), c
->n_log_extra_fields
+1);
1237 c
->log_extra_fields
= t
;
1240 copy
= malloc(sz
+ 1);
1244 memcpy(copy
, p
, sz
);
1245 ((uint8_t*) copy
)[sz
] = 0;
1247 if (!utf8_is_valid(copy
))
1248 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Journal field is not valid UTF-8");
1250 if (mode
!= UNIT_CHECK
) {
1251 c
->log_extra_fields
[c
->n_log_extra_fields
++] = IOVEC_MAKE(copy
, sz
);
1252 unit_write_drop_in_private_format(u
, mode
, name
, "LogExtraFields=%s", (char*) copy
);
1260 r
= sd_bus_message_exit_container(message
);
1264 if (mode
!= UNIT_CHECK
&& n
== 0) {
1265 exec_context_free_log_extra_fields(c
);
1266 unit_write_drop_in_private(u
, mode
, name
, "LogExtraFields=");
1271 } else if (streq(name
, "SecureBits")) {
1274 r
= sd_bus_message_read(message
, "i", &n
);
1278 if (!secure_bits_is_valid(n
))
1279 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid secure bits");
1281 if (mode
!= UNIT_CHECK
) {
1282 _cleanup_free_
char *str
= NULL
;
1285 r
= secure_bits_to_string_alloc(n
, &str
);
1289 unit_write_drop_in_private_format(u
, mode
, name
, "SecureBits=%s", str
);
1293 } else if (STR_IN_SET(name
, "CapabilityBoundingSet", "AmbientCapabilities")) {
1296 r
= sd_bus_message_read(message
, "t", &n
);
1300 if (mode
!= UNIT_CHECK
) {
1301 _cleanup_free_
char *str
= NULL
;
1303 if (streq(name
, "CapabilityBoundingSet"))
1304 c
->capability_bounding_set
= n
;
1305 else /* "AmbientCapabilities" */
1306 c
->capability_ambient_set
= n
;
1308 r
= capability_set_to_string_alloc(n
, &str
);
1312 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, str
);
1317 } else if (streq(name
, "Personality")) {
1321 r
= sd_bus_message_read(message
, "s", &s
);
1325 p
= personality_from_string(s
);
1326 if (p
== PERSONALITY_INVALID
)
1327 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid personality");
1329 if (mode
!= UNIT_CHECK
) {
1331 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
1338 } else if (streq(name
, "SystemCallFilter")) {
1340 _cleanup_strv_free_
char **l
= NULL
;
1342 r
= sd_bus_message_enter_container(message
, 'r', "bas");
1346 r
= sd_bus_message_read(message
, "b", &whitelist
);
1350 r
= sd_bus_message_read_strv(message
, &l
);
1354 r
= sd_bus_message_exit_container(message
);
1358 if (mode
!= UNIT_CHECK
) {
1359 _cleanup_free_
char *joined
= NULL
;
1361 if (strv_length(l
) == 0) {
1362 c
->syscall_whitelist
= false;
1363 c
->syscall_filter
= hashmap_free(c
->syscall_filter
);
1367 c
->syscall_whitelist
= whitelist
;
1369 r
= hashmap_ensure_allocated(&c
->syscall_filter
, NULL
);
1373 STRV_FOREACH(s
, l
) {
1374 _cleanup_free_
char *n
= NULL
;
1377 r
= parse_syscall_and_errno(*s
, &n
, &e
);
1382 const SyscallFilterSet
*set
;
1385 set
= syscall_filter_set_find(n
);
1389 NULSTR_FOREACH(i
, set
->value
) {
1392 id
= seccomp_syscall_resolve_name(i
);
1393 if (id
== __NR_SCMP_ERROR
)
1396 r
= hashmap_put(c
->syscall_filter
, INT_TO_PTR(id
+ 1), INT_TO_PTR(e
));
1404 id
= seccomp_syscall_resolve_name(n
);
1405 if (id
== __NR_SCMP_ERROR
)
1408 r
= hashmap_put(c
->syscall_filter
, INT_TO_PTR(id
+ 1), INT_TO_PTR(e
));
1415 joined
= strv_join(l
, " ");
1419 unit_write_drop_in_private_format(u
, mode
, name
, "SystemCallFilter=%s%s", whitelist
? "" : "~", joined
);
1424 } else if (streq(name
, "SystemCallArchitectures")) {
1425 _cleanup_strv_free_
char **l
= NULL
;
1427 r
= sd_bus_message_read_strv(message
, &l
);
1431 if (mode
!= UNIT_CHECK
) {
1432 _cleanup_free_
char *joined
= NULL
;
1434 if (strv_length(l
) == 0)
1435 c
->syscall_archs
= set_free(c
->syscall_archs
);
1439 r
= set_ensure_allocated(&c
->syscall_archs
, NULL
);
1443 STRV_FOREACH(s
, l
) {
1446 r
= seccomp_arch_from_string(*s
, &a
);
1450 r
= set_put(c
->syscall_archs
, UINT32_TO_PTR(a
+ 1));
1457 joined
= strv_join(l
, " ");
1461 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
1466 } else if (streq(name
, "SystemCallErrorNumber")) {
1469 r
= sd_bus_message_read(message
, "i", &n
);
1473 if (n
<= 0 || n
> ERRNO_MAX
)
1474 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid SystemCallErrorNumber");
1476 if (mode
!= UNIT_CHECK
) {
1477 c
->syscall_errno
= n
;
1479 unit_write_drop_in_private_format(u
, mode
, name
, "SystemCallErrorNumber=%d", n
);
1484 } else if (streq(name
, "RestrictAddressFamilies")) {
1486 _cleanup_strv_free_
char **l
= NULL
;
1488 r
= sd_bus_message_enter_container(message
, 'r', "bas");
1492 r
= sd_bus_message_read(message
, "b", &whitelist
);
1496 r
= sd_bus_message_read_strv(message
, &l
);
1500 r
= sd_bus_message_exit_container(message
);
1504 if (mode
!= UNIT_CHECK
) {
1505 _cleanup_free_
char *joined
= NULL
;
1507 if (strv_length(l
) == 0) {
1508 c
->address_families_whitelist
= false;
1509 c
->address_families
= set_free(c
->address_families
);
1513 c
->address_families_whitelist
= whitelist
;
1515 r
= set_ensure_allocated(&c
->address_families
, NULL
);
1519 STRV_FOREACH(s
, l
) {
1522 af
= af_from_name(*s
);
1526 r
= set_put(c
->address_families
, INT_TO_PTR(af
));
1532 joined
= strv_join(l
, " ");
1536 unit_write_drop_in_private_format(u
, mode
, name
, "RestrictAddressFamilies=%s%s", whitelist
? "" : "~", joined
);
1542 } else if (streq(name
, "CPUSchedulingPolicy")) {
1545 r
= sd_bus_message_read(message
, "i", &n
);
1549 if (!sched_policy_is_valid(n
))
1550 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid CPU scheduling policy");
1552 if (mode
!= UNIT_CHECK
) {
1553 _cleanup_free_
char *str
= NULL
;
1555 c
->cpu_sched_policy
= n
;
1556 r
= sched_policy_to_string_alloc(n
, &str
);
1560 unit_write_drop_in_private_format(u
, mode
, name
, "CPUSchedulingPolicy=%s", str
);
1565 } else if (streq(name
, "CPUSchedulingPriority")) {
1568 r
= sd_bus_message_read(message
, "i", &n
);
1572 if (!ioprio_priority_is_valid(n
))
1573 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid CPU scheduling priority");
1575 if (mode
!= UNIT_CHECK
) {
1576 c
->cpu_sched_priority
= n
;
1577 unit_write_drop_in_private_format(u
, mode
, name
, "CPUSchedulingPriority=%i", n
);
1582 } else if (streq(name
, "CPUAffinity")) {
1586 r
= sd_bus_message_read_array(message
, 'y', &a
, &n
);
1590 if (mode
!= UNIT_CHECK
) {
1592 c
->cpuset
= mfree(c
->cpuset
);
1593 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
1595 _cleanup_free_
char *str
= NULL
;
1597 size_t allocated
= 0, len
= 0, i
;
1599 c
->cpuset
= (cpu_set_t
*) memdup(a
, sizeof(cpu_set_t
) * n
);
1604 for (i
= 0; i
< n
; i
++) {
1605 _cleanup_free_
char *p
= NULL
;
1608 r
= asprintf(&p
, "%hhi", l
[i
]);
1614 if (GREEDY_REALLOC(str
, allocated
, len
+ add
+ 2))
1617 strcpy(mempcpy(str
+ len
, p
, add
), " ");
1622 str
[len
- 1] = '\0';
1624 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, str
);
1629 } else if (streq(name
, "Nice")) {
1632 r
= sd_bus_message_read(message
, "i", &n
);
1636 if (!nice_is_valid(n
))
1637 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Nice value out of range");
1639 if (mode
!= UNIT_CHECK
) {
1641 unit_write_drop_in_private_format(u
, mode
, name
, "Nice=%i", n
);
1646 } else if (streq(name
, "IOSchedulingClass")) {
1649 r
= sd_bus_message_read(message
, "i", &q
);
1653 if (!ioprio_class_is_valid(q
))
1654 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid IO scheduling class: %i", q
);
1656 if (mode
!= UNIT_CHECK
) {
1657 _cleanup_free_
char *s
= NULL
;
1659 r
= ioprio_class_to_string_alloc(q
, &s
);
1663 c
->ioprio
= IOPRIO_PRIO_VALUE(q
, IOPRIO_PRIO_DATA(c
->ioprio
));
1664 c
->ioprio_set
= true;
1666 unit_write_drop_in_private_format(u
, mode
, name
, "IOSchedulingClass=%s", s
);
1671 } else if (streq(name
, "IOSchedulingPriority")) {
1674 r
= sd_bus_message_read(message
, "i", &p
);
1678 if (!ioprio_priority_is_valid(p
))
1679 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid IO scheduling priority: %i", p
);
1681 if (mode
!= UNIT_CHECK
) {
1682 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c
->ioprio
), p
);
1683 c
->ioprio_set
= true;
1685 unit_write_drop_in_private_format(u
, mode
, name
, "IOSchedulingPriority=%i", p
);
1690 } else if (STR_IN_SET(name
, "TTYPath", "RootDirectory", "RootImage")) {
1693 r
= sd_bus_message_read(message
, "s", &s
);
1697 if (!path_is_absolute(s
))
1698 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s takes an absolute path", name
);
1700 if (mode
!= UNIT_CHECK
) {
1701 if (streq(name
, "TTYPath"))
1702 r
= free_and_strdup(&c
->tty_path
, s
);
1703 else if (streq(name
, "RootImage"))
1704 r
= free_and_strdup(&c
->root_image
, s
);
1706 assert(streq(name
, "RootDirectory"));
1707 r
= free_and_strdup(&c
->root_directory
, s
);
1712 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
1717 } else if (streq(name
, "WorkingDirectory")) {
1721 r
= sd_bus_message_read(message
, "s", &s
);
1731 if (!streq(s
, "~") && !path_is_absolute(s
))
1732 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "WorkingDirectory= expects an absolute path or '~'");
1734 if (mode
!= UNIT_CHECK
) {
1735 if (streq(s
, "~")) {
1736 c
->working_directory
= mfree(c
->working_directory
);
1737 c
->working_directory_home
= true;
1739 r
= free_and_strdup(&c
->working_directory
, s
);
1743 c
->working_directory_home
= false;
1746 c
->working_directory_missing_ok
= missing_ok
;
1747 unit_write_drop_in_private_format(u
, mode
, name
, "WorkingDirectory=%s%s", missing_ok
? "-" : "", s
);
1752 } else if (streq(name
, "StandardInput")) {
1756 r
= sd_bus_message_read(message
, "s", &s
);
1760 p
= exec_input_from_string(s
);
1762 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard input name");
1764 if (mode
!= UNIT_CHECK
) {
1767 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInput=%s", exec_input_to_string(p
));
1772 } else if (streq(name
, "StandardOutput")) {
1776 r
= sd_bus_message_read(message
, "s", &s
);
1780 p
= exec_output_from_string(s
);
1782 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard output name");
1784 if (mode
!= UNIT_CHECK
) {
1787 unit_write_drop_in_private_format(u
, mode
, name
, "StandardOutput=%s", exec_output_to_string(p
));
1792 } else if (streq(name
, "StandardError")) {
1796 r
= sd_bus_message_read(message
, "s", &s
);
1800 p
= exec_output_from_string(s
);
1802 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard error name");
1804 if (mode
!= UNIT_CHECK
) {
1807 unit_write_drop_in_private_format(u
, mode
, name
, "StandardError=%s", exec_output_to_string(p
));
1812 } else if (STR_IN_SET(name
,
1813 "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
1816 r
= sd_bus_message_read(message
, "s", &s
);
1822 else if (!fdname_is_valid(s
))
1823 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid file descriptor name");
1825 if (mode
!= UNIT_CHECK
) {
1827 if (streq(name
, "StandardInputFileDescriptorName")) {
1828 r
= free_and_strdup(c
->stdio_fdname
+ STDIN_FILENO
, s
);
1832 c
->std_input
= EXEC_INPUT_NAMED_FD
;
1833 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInput=fd:%s", exec_context_fdname(c
, STDIN_FILENO
));
1835 } else if (streq(name
, "StandardOutputFileDescriptorName")) {
1836 r
= free_and_strdup(c
->stdio_fdname
+ STDOUT_FILENO
, s
);
1840 c
->std_output
= EXEC_OUTPUT_NAMED_FD
;
1841 unit_write_drop_in_private_format(u
, mode
, name
, "StandardOutput=fd:%s", exec_context_fdname(c
, STDOUT_FILENO
));
1844 assert(streq(name
, "StandardErrorFileDescriptorName"));
1846 r
= free_and_strdup(&c
->stdio_fdname
[STDERR_FILENO
], s
);
1850 c
->std_error
= EXEC_OUTPUT_NAMED_FD
;
1851 unit_write_drop_in_private_format(u
, mode
, name
, "StandardError=fd:%s", exec_context_fdname(c
, STDERR_FILENO
));
1857 } else if (STR_IN_SET(name
, "StandardInputFile", "StandardOutputFile", "StandardErrorFile")) {
1860 r
= sd_bus_message_read(message
, "s", &s
);
1864 if (!path_is_absolute(s
))
1865 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path %s is not absolute", s
);
1866 if (!path_is_normalized(s
))
1867 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path %s is not normalized", s
);
1869 if (mode
!= UNIT_CHECK
) {
1871 if (streq(name
, "StandardInputFile")) {
1872 r
= free_and_strdup(&c
->stdio_file
[STDIN_FILENO
], s
);
1876 c
->std_input
= EXEC_INPUT_FILE
;
1877 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInput=file:%s", s
);
1879 } else if (streq(name
, "StandardOutputFile")) {
1880 r
= free_and_strdup(&c
->stdio_file
[STDOUT_FILENO
], s
);
1884 c
->std_output
= EXEC_OUTPUT_FILE
;
1885 unit_write_drop_in_private_format(u
, mode
, name
, "StandardOutput=file:%s", s
);
1888 assert(streq(name
, "StandardErrorFile"));
1890 r
= free_and_strdup(&c
->stdio_file
[STDERR_FILENO
], s
);
1894 c
->std_error
= EXEC_OUTPUT_FILE
;
1895 unit_write_drop_in_private_format(u
, mode
, name
, "StandardError=file:%s", s
);
1901 } else if (streq(name
, "StandardInputData")) {
1905 r
= sd_bus_message_read_array(message
, 'y', &p
, &sz
);
1909 if (mode
!= UNIT_CHECK
) {
1910 _cleanup_free_
char *encoded
= NULL
;
1913 c
->stdin_data
= mfree(c
->stdin_data
);
1914 c
->stdin_data_size
= 0;
1916 unit_write_drop_in_private(u
, mode
, name
, "StandardInputData=");
1921 if (c
->stdin_data_size
+ sz
< c
->stdin_data_size
|| /* check for overflow */
1922 c
->stdin_data_size
+ sz
> EXEC_STDIN_DATA_MAX
)
1925 n
= base64mem(p
, sz
, &encoded
);
1929 q
= realloc(c
->stdin_data
, c
->stdin_data_size
+ sz
);
1933 memcpy((uint8_t*) q
+ c
->stdin_data_size
, p
, sz
);
1936 c
->stdin_data_size
+= sz
;
1938 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInputData=%s", encoded
);
1944 } else if (STR_IN_SET(name
,
1945 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
1946 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
1947 "NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
1948 "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
1949 "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
1950 "CPUSchedulingResetOnFork", "NonBlocking", "LockPersonality")) {
1953 r
= sd_bus_message_read(message
, "b", &b
);
1957 if (mode
!= UNIT_CHECK
) {
1958 if (streq(name
, "IgnoreSIGPIPE"))
1959 c
->ignore_sigpipe
= b
;
1960 else if (streq(name
, "TTYVHangup"))
1962 else if (streq(name
, "TTYReset"))
1964 else if (streq(name
, "TTYVTDisallocate"))
1965 c
->tty_vt_disallocate
= b
;
1966 else if (streq(name
, "PrivateTmp"))
1968 else if (streq(name
, "PrivateDevices"))
1969 c
->private_devices
= b
;
1970 else if (streq(name
, "PrivateNetwork"))
1971 c
->private_network
= b
;
1972 else if (streq(name
, "PrivateUsers"))
1973 c
->private_users
= b
;
1974 else if (streq(name
, "NoNewPrivileges"))
1975 c
->no_new_privileges
= b
;
1976 else if (streq(name
, "SyslogLevelPrefix"))
1977 c
->syslog_level_prefix
= b
;
1978 else if (streq(name
, "MemoryDenyWriteExecute"))
1979 c
->memory_deny_write_execute
= b
;
1980 else if (streq(name
, "RestrictRealtime"))
1981 c
->restrict_realtime
= b
;
1982 else if (streq(name
, "DynamicUser"))
1983 c
->dynamic_user
= b
;
1984 else if (streq(name
, "RemoveIPC"))
1986 else if (streq(name
, "ProtectKernelTunables"))
1987 c
->protect_kernel_tunables
= b
;
1988 else if (streq(name
, "ProtectKernelModules"))
1989 c
->protect_kernel_modules
= b
;
1990 else if (streq(name
, "ProtectControlGroups"))
1991 c
->protect_control_groups
= b
;
1992 else if (streq(name
, "MountAPIVFS"))
1993 c
->mount_apivfs
= b
;
1994 else if (streq(name
, "CPUSchedulingResetOnFork"))
1995 c
->cpu_sched_reset_on_fork
= b
;
1996 else if (streq(name
, "NonBlocking"))
1997 c
->non_blocking
= b
;
1998 else if (streq(name
, "LockPersonality"))
1999 c
->lock_personality
= b
;
2001 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, yes_no(b
));
2006 } else if (streq(name
, "UtmpIdentifier")) {
2009 r
= sd_bus_message_read(message
, "s", &id
);
2013 if (mode
!= UNIT_CHECK
) {
2015 c
->utmp_id
= mfree(c
->utmp_id
);
2016 else if (free_and_strdup(&c
->utmp_id
, id
) < 0)
2019 unit_write_drop_in_private_format(u
, mode
, name
, "UtmpIdentifier=%s", strempty(id
));
2024 } else if (streq(name
, "UtmpMode")) {
2028 r
= sd_bus_message_read(message
, "s", &s
);
2032 m
= exec_utmp_mode_from_string(s
);
2034 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid utmp mode");
2036 if (mode
!= UNIT_CHECK
) {
2039 unit_write_drop_in_private_format(u
, mode
, name
, "UtmpMode=%s", exec_utmp_mode_to_string(m
));
2044 } else if (streq(name
, "PAMName")) {
2047 r
= sd_bus_message_read(message
, "s", &n
);
2051 if (mode
!= UNIT_CHECK
) {
2053 c
->pam_name
= mfree(c
->pam_name
);
2054 else if (free_and_strdup(&c
->pam_name
, n
) < 0)
2057 unit_write_drop_in_private_format(u
, mode
, name
, "PAMName=%s", strempty(n
));
2062 } else if (streq(name
, "Environment")) {
2064 _cleanup_strv_free_
char **l
= NULL
, **q
= NULL
;
2066 r
= sd_bus_message_read_strv(message
, &l
);
2070 r
= unit_full_printf_strv(u
, l
, &q
);
2074 if (!strv_env_is_valid(q
))
2075 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment block.");
2077 if (mode
!= UNIT_CHECK
) {
2078 if (strv_length(q
) == 0) {
2079 c
->environment
= strv_free(c
->environment
);
2080 unit_write_drop_in_private_format(u
, mode
, name
, "Environment=");
2082 _cleanup_free_
char *joined
= NULL
;
2085 e
= strv_env_merge(2, c
->environment
, q
);
2089 strv_free(c
->environment
);
2092 /* We write just the new settings out to file, with unresolved specifiers */
2093 joined
= strv_join_quoted(l
);
2097 unit_write_drop_in_private_format(u
, mode
, name
, "Environment=%s", joined
);
2103 } else if (streq(name
, "UnsetEnvironment")) {
2105 _cleanup_strv_free_
char **l
= NULL
, **q
= NULL
;
2107 r
= sd_bus_message_read_strv(message
, &l
);
2111 r
= unit_full_printf_strv(u
, l
, &q
);
2115 if (!strv_env_name_or_assignment_is_valid(q
))
2116 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid UnsetEnvironment= list.");
2118 if (mode
!= UNIT_CHECK
) {
2119 if (strv_length(q
) == 0) {
2120 c
->unset_environment
= strv_free(c
->unset_environment
);
2121 unit_write_drop_in_private_format(u
, mode
, name
, "UnsetEnvironment=");
2123 _cleanup_free_
char *joined
= NULL
;
2126 e
= strv_env_merge(2, c
->unset_environment
, q
);
2130 strv_free(c
->unset_environment
);
2131 c
->unset_environment
= e
;
2133 /* We write just the new settings out to file, with unresolved specifiers */
2134 joined
= strv_join_quoted(l
);
2138 unit_write_drop_in_private_format(u
, mode
, name
, "UnsetEnvironment=%s", joined
);
2144 } else if (streq(name
, "TimerSlackNSec")) {
2148 r
= sd_bus_message_read(message
, "t", &n
);
2152 if (mode
!= UNIT_CHECK
) {
2153 c
->timer_slack_nsec
= n
;
2154 unit_write_drop_in_private_format(u
, mode
, name
, "TimerSlackNSec=" NSEC_FMT
, n
);
2159 } else if (streq(name
, "OOMScoreAdjust")) {
2162 r
= sd_bus_message_read(message
, "i", &oa
);
2166 if (!oom_score_adjust_is_valid(oa
))
2167 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "OOM score adjust value out of range");
2169 if (mode
!= UNIT_CHECK
) {
2170 c
->oom_score_adjust
= oa
;
2171 c
->oom_score_adjust_set
= true;
2172 unit_write_drop_in_private_format(u
, mode
, name
, "OOMScoreAdjust=%i", oa
);
2177 } else if (streq(name
, "EnvironmentFiles")) {
2179 _cleanup_free_
char *joined
= NULL
;
2180 _cleanup_fclose_
FILE *f
= NULL
;
2181 _cleanup_strv_free_
char **l
= NULL
;
2185 r
= sd_bus_message_enter_container(message
, 'a', "(sb)");
2189 f
= open_memstream(&joined
, &size
);
2193 STRV_FOREACH(i
, c
->environment_files
)
2194 fprintf(f
, "EnvironmentFile=%s", *i
);
2196 while ((r
= sd_bus_message_enter_container(message
, 'r', "sb")) > 0) {
2200 r
= sd_bus_message_read(message
, "sb", &path
, &b
);
2204 r
= sd_bus_message_exit_container(message
);
2208 if (!path_is_absolute(path
))
2209 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path %s is not absolute.", path
);
2211 if (mode
!= UNIT_CHECK
) {
2214 buf
= strjoin(b
? "-" : "", path
);
2218 fprintf(f
, "EnvironmentFile=%s", buf
);
2220 r
= strv_consume(&l
, buf
);
2228 r
= sd_bus_message_exit_container(message
);
2232 r
= fflush_and_check(f
);
2236 if (mode
!= UNIT_CHECK
) {
2237 if (strv_isempty(l
)) {
2238 c
->environment_files
= strv_free(c
->environment_files
);
2239 unit_write_drop_in_private(u
, mode
, name
, "EnvironmentFile=");
2241 r
= strv_extend_strv(&c
->environment_files
, l
, true);
2245 unit_write_drop_in_private(u
, mode
, name
, joined
);
2251 } else if (streq(name
, "PassEnvironment")) {
2253 _cleanup_strv_free_
char **l
= NULL
, **q
= NULL
;
2255 r
= sd_bus_message_read_strv(message
, &l
);
2259 r
= unit_full_printf_strv(u
, l
, &q
);
2263 if (!strv_env_name_is_valid(q
))
2264 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid PassEnvironment= block.");
2266 if (mode
!= UNIT_CHECK
) {
2267 if (strv_isempty(l
)) {
2268 c
->pass_environment
= strv_free(c
->pass_environment
);
2269 unit_write_drop_in_private_format(u
, mode
, name
, "PassEnvironment=");
2271 _cleanup_free_
char *joined
= NULL
;
2273 r
= strv_extend_strv(&c
->pass_environment
, q
, true);
2277 /* We write just the new settings out to file, with unresolved specifiers. */
2278 joined
= strv_join_quoted(l
);
2282 unit_write_drop_in_private_format(u
, mode
, name
, "PassEnvironment=%s", joined
);
2288 } else if (STR_IN_SET(name
, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
2289 "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
2290 _cleanup_strv_free_
char **l
= NULL
;
2294 r
= sd_bus_message_read_strv(message
, &l
);
2298 STRV_FOREACH(p
, l
) {
2302 if (!utf8_is_valid(i
))
2303 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid %s", name
);
2305 offset
= i
[0] == '-';
2306 offset
+= i
[offset
] == '+';
2307 if (!path_is_absolute(i
+ offset
))
2308 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid %s", name
);
2311 if (mode
!= UNIT_CHECK
) {
2312 _cleanup_free_
char *joined
= NULL
;
2314 if (STR_IN_SET(name
, "ReadWriteDirectories", "ReadWritePaths"))
2315 dirs
= &c
->read_write_paths
;
2316 else if (STR_IN_SET(name
, "ReadOnlyDirectories", "ReadOnlyPaths"))
2317 dirs
= &c
->read_only_paths
;
2318 else /* "InaccessiblePaths" */
2319 dirs
= &c
->inaccessible_paths
;
2321 if (strv_length(l
) == 0) {
2322 *dirs
= strv_free(*dirs
);
2323 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
2325 r
= strv_extend_strv(dirs
, l
, true);
2329 joined
= strv_join_quoted(*dirs
);
2333 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
2340 } else if (streq(name
, "ProtectSystem")) {
2344 r
= sd_bus_message_read(message
, "s", &s
);
2348 r
= parse_boolean(s
);
2350 ps
= PROTECT_SYSTEM_YES
;
2352 ps
= PROTECT_SYSTEM_NO
;
2354 ps
= protect_system_from_string(s
);
2356 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Failed to parse protect system value");
2359 if (mode
!= UNIT_CHECK
) {
2360 c
->protect_system
= ps
;
2361 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
2366 } else if (streq(name
, "ProtectHome")) {
2370 r
= sd_bus_message_read(message
, "s", &s
);
2374 r
= parse_boolean(s
);
2376 ph
= PROTECT_HOME_YES
;
2378 ph
= PROTECT_HOME_NO
;
2380 ph
= protect_home_from_string(s
);
2382 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Failed to parse protect home value");
2385 if (mode
!= UNIT_CHECK
) {
2386 c
->protect_home
= ph
;
2387 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
2392 } else if (streq(name
, "KeyringMode")) {
2397 r
= sd_bus_message_read(message
, "s", &s
);
2401 m
= exec_keyring_mode_from_string(s
);
2403 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid keyring mode");
2405 if (mode
!= UNIT_CHECK
) {
2406 c
->keyring_mode
= m
;
2408 unit_write_drop_in_private_format(u
, mode
, name
, "KeyringMode=%s", exec_keyring_mode_to_string(m
));
2413 } else if (streq(name
, "RuntimeDirectoryPreserve")) {
2417 r
= sd_bus_message_read(message
, "s", &s
);
2421 m
= exec_preserve_mode_from_string(s
);
2423 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid preserve mode");
2425 if (mode
!= UNIT_CHECK
) {
2426 c
->runtime_directory_preserve_mode
= m
;
2428 unit_write_drop_in_private_format(u
, mode
, name
, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m
));
2433 } else if (STR_IN_SET(name
, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) {
2436 r
= sd_bus_message_read(message
, "u", &m
);
2440 if (mode
!= UNIT_CHECK
) {
2441 ExecDirectoryType i
;
2443 if (streq(name
, "UMask"))
2446 for (i
= 0; i
< _EXEC_DIRECTORY_TYPE_MAX
; i
++)
2447 if (startswith(name
, exec_directory_type_to_string(i
))) {
2448 c
->directories
[i
].mode
= m
;
2452 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%040o", name
, m
);
2457 } else if (STR_IN_SET(name
, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
2458 _cleanup_strv_free_
char **l
= NULL
;
2461 r
= sd_bus_message_read_strv(message
, &l
);
2465 STRV_FOREACH(p
, l
) {
2466 if (!path_is_normalized(*p
) || path_is_absolute(*p
))
2467 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= path is not valid: %s", name
, *p
);
2470 if (mode
!= UNIT_CHECK
) {
2471 _cleanup_free_
char *joined
= NULL
;
2472 char ***dirs
= NULL
;
2473 ExecDirectoryType i
;
2475 for (i
= 0; i
< _EXEC_DIRECTORY_TYPE_MAX
; i
++)
2476 if (streq(name
, exec_directory_type_to_string(i
))) {
2477 dirs
= &c
->directories
[i
].paths
;
2483 if (strv_isempty(l
)) {
2484 *dirs
= strv_free(*dirs
);
2485 unit_write_drop_in_private_format(u
, mode
, name
, "%s=", name
);
2487 r
= strv_extend_strv(dirs
, l
, true);
2491 joined
= strv_join_quoted(*dirs
);
2495 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, joined
);
2501 } else if (streq(name
, "SELinuxContext")) {
2503 r
= sd_bus_message_read(message
, "s", &s
);
2507 if (mode
!= UNIT_CHECK
) {
2509 c
->selinux_context
= mfree(c
->selinux_context
);
2510 else if (free_and_strdup(&c
->selinux_context
, s
) < 0)
2513 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, strempty(s
));
2518 } else if (STR_IN_SET(name
, "AppArmorProfile", "SmackProcessLabel")) {
2522 r
= sd_bus_message_enter_container(message
, 'r', "bs");
2526 r
= sd_bus_message_read(message
, "bs", &ignore
, &s
);
2530 if (mode
!= UNIT_CHECK
) {
2534 if (streq(name
, "AppArmorProfile")) {
2535 p
= &c
->apparmor_profile
;
2536 b
= &c
->apparmor_profile_ignore
;
2537 } else { /* "SmackProcessLabel" */
2538 p
= &c
->smack_process_label
;
2539 b
= &c
->smack_process_label_ignore
;
2546 if (free_and_strdup(p
, s
) < 0)
2551 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s%s", name
, ignore
? "-" : "", strempty(s
));
2556 } else if (streq(name
, "RestrictNamespaces")) {
2559 r
= sd_bus_message_read(message
, "t", &flags
);
2562 if ((flags
& NAMESPACE_FLAGS_ALL
) != flags
)
2563 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown namespace types");
2565 if (mode
!= UNIT_CHECK
) {
2566 _cleanup_free_
char *s
= NULL
;
2568 r
= namespace_flag_to_string_many(flags
, &s
);
2572 c
->restrict_namespaces
= flags
;
2573 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, s
);
2577 } else if (streq(name
, "MountFlags")) {
2580 r
= sd_bus_message_read(message
, "t", &flags
);
2583 if (!IN_SET(flags
, 0, MS_SHARED
, MS_PRIVATE
, MS_SLAVE
))
2584 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown mount propagation flags");
2586 if (mode
!= UNIT_CHECK
) {
2587 c
->mount_flags
= flags
;
2589 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, mount_propagation_flags_to_string(flags
));
2593 } else if (STR_IN_SET(name
, "BindPaths", "BindReadOnlyPaths")) {
2594 unsigned empty
= true;
2596 r
= sd_bus_message_enter_container(message
, 'a', "(ssbt)");
2600 while ((r
= sd_bus_message_enter_container(message
, 'r', "ssbt")) > 0) {
2601 const char *source
, *destination
;
2603 uint64_t mount_flags
;
2605 r
= sd_bus_message_read(message
, "ssbt", &source
, &destination
, &ignore_enoent
, &mount_flags
);
2609 r
= sd_bus_message_exit_container(message
);
2613 if (!path_is_absolute(source
))
2614 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Source path %s is not absolute.", source
);
2615 if (!path_is_absolute(destination
))
2616 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Destination path %s is not absolute.", destination
);
2617 if (!IN_SET(mount_flags
, 0, MS_REC
))
2618 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown mount flags.");
2620 if (mode
!= UNIT_CHECK
) {
2621 r
= bind_mount_add(&c
->bind_mounts
, &c
->n_bind_mounts
,
2623 .source
= strdup(source
),
2624 .destination
= strdup(destination
),
2625 .read_only
= !!strstr(name
, "ReadOnly"),
2626 .recursive
= !!(mount_flags
& MS_REC
),
2627 .ignore_enoent
= ignore_enoent
,
2632 unit_write_drop_in_private_format(
2636 ignore_enoent
? "-" : "",
2639 (mount_flags
& MS_REC
) ? "rbind" : "norbind");
2647 r
= sd_bus_message_exit_container(message
);
2652 bind_mount_free_many(c
->bind_mounts
, c
->n_bind_mounts
);
2653 c
->bind_mounts
= NULL
;
2654 c
->n_bind_mounts
= 0;
2660 ri
= rlimit_from_string(name
);
2662 soft
= endswith(name
, "Soft");
2666 n
= strndupa(name
, soft
- name
);
2667 ri
= rlimit_from_string(n
);
2678 r
= sd_bus_message_read(message
, "t", &rl
);
2682 if (rl
== (uint64_t) -1)
2687 if ((uint64_t) x
!= rl
)
2691 if (mode
!= UNIT_CHECK
) {
2692 _cleanup_free_
char *f
= NULL
;
2695 if (c
->rlimit
[ri
]) {
2696 nl
= *c
->rlimit
[ri
];
2703 /* When the resource limit is not initialized yet, then assign the value to both fields */
2704 nl
= (struct rlimit
) {
2709 r
= rlimit_format(&nl
, &f
);
2714 *c
->rlimit
[ri
] = nl
;
2716 c
->rlimit
[ri
] = newdup(struct rlimit
, &nl
, 1);
2721 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s", name
, f
);