1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/prctl.h>
34 #include "capability.h"
37 #include "namespace.h"
38 #include "path-util.h"
39 #include "dbus-execute.h"
42 #include "seccomp-util.h"
45 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output
, exec_output
, ExecOutput
);
47 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input
, exec_input
, ExecInput
);
49 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode
, exec_utmp_mode
, ExecUtmpMode
);
51 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home
, protect_home
, ProtectHome
);
52 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system
, protect_system
, ProtectSystem
);
54 static int property_get_environment_files(
57 const char *interface
,
59 sd_bus_message
*reply
,
61 sd_bus_error
*error
) {
63 ExecContext
*c
= userdata
;
71 r
= sd_bus_message_open_container(reply
, 'a', "(sb)");
75 STRV_FOREACH(j
, c
->environment_files
) {
78 r
= sd_bus_message_append(reply
, "(sb)", fn
[0] == '-' ? fn
+ 1 : fn
, fn
[0] == '-');
83 return sd_bus_message_close_container(reply
);
86 static int property_get_rlimit(
89 const char *interface
,
91 sd_bus_message
*reply
,
93 sd_bus_error
*error
) {
103 rl
= *(struct rlimit
**) userdata
;
107 struct rlimit buf
= {};
110 z
= rlimit_from_string(property
);
117 /* rlim_t might have different sizes, let's map
118 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
120 u
= x
== RLIM_INFINITY
? (uint64_t) -1 : (uint64_t) x
;
122 return sd_bus_message_append(reply
, "t", u
);
125 static int property_get_oom_score_adjust(
128 const char *interface
,
129 const char *property
,
130 sd_bus_message
*reply
,
132 sd_bus_error
*error
) {
135 ExecContext
*c
= userdata
;
142 if (c
->oom_score_adjust_set
)
143 n
= c
->oom_score_adjust
;
145 _cleanup_free_
char *t
= NULL
;
148 if (read_one_line_file("/proc/self/oom_score_adj", &t
) >= 0)
152 return sd_bus_message_append(reply
, "i", n
);
155 static int property_get_nice(
158 const char *interface
,
159 const char *property
,
160 sd_bus_message
*reply
,
162 sd_bus_error
*error
) {
165 ExecContext
*c
= userdata
;
176 n
= getpriority(PRIO_PROCESS
, 0);
181 return sd_bus_message_append(reply
, "i", n
);
184 static int property_get_ioprio(
187 const char *interface
,
188 const char *property
,
189 sd_bus_message
*reply
,
191 sd_bus_error
*error
) {
194 ExecContext
*c
= userdata
;
204 n
= ioprio_get(IOPRIO_WHO_PROCESS
, 0);
206 n
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 4);
209 return sd_bus_message_append(reply
, "i", n
);
212 static int property_get_cpu_sched_policy(
215 const char *interface
,
216 const char *property
,
217 sd_bus_message
*reply
,
219 sd_bus_error
*error
) {
221 ExecContext
*c
= userdata
;
228 if (c
->cpu_sched_set
)
229 n
= c
->cpu_sched_policy
;
231 n
= sched_getscheduler(0);
236 return sd_bus_message_append(reply
, "i", n
);
239 static int property_get_cpu_sched_priority(
242 const char *interface
,
243 const char *property
,
244 sd_bus_message
*reply
,
246 sd_bus_error
*error
) {
248 ExecContext
*c
= userdata
;
255 if (c
->cpu_sched_set
)
256 n
= c
->cpu_sched_priority
;
258 struct sched_param p
= {};
260 if (sched_getparam(0, &p
) >= 0)
261 n
= p
.sched_priority
;
266 return sd_bus_message_append(reply
, "i", n
);
269 static int property_get_cpu_affinity(
272 const char *interface
,
273 const char *property
,
274 sd_bus_message
*reply
,
276 sd_bus_error
*error
) {
278 ExecContext
*c
= userdata
;
285 return sd_bus_message_append_array(reply
, 'y', c
->cpuset
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
));
287 return sd_bus_message_append_array(reply
, 'y', NULL
, 0);
290 static int property_get_timer_slack_nsec(
293 const char *interface
,
294 const char *property
,
295 sd_bus_message
*reply
,
297 sd_bus_error
*error
) {
299 ExecContext
*c
= userdata
;
306 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
307 u
= (uint64_t) c
->timer_slack_nsec
;
309 u
= (uint64_t) prctl(PR_GET_TIMERSLACK
);
311 return sd_bus_message_append(reply
, "t", u
);
314 static int property_get_capability_bounding_set(
317 const char *interface
,
318 const char *property
,
319 sd_bus_message
*reply
,
321 sd_bus_error
*error
) {
323 ExecContext
*c
= userdata
;
329 /* We store this negated internally, to match the kernel, but
330 * we expose it normalized. */
331 return sd_bus_message_append(reply
, "t", ~c
->capability_bounding_set_drop
);
334 static int property_get_capabilities(
337 const char *interface
,
338 const char *property
,
339 sd_bus_message
*reply
,
341 sd_bus_error
*error
) {
343 ExecContext
*c
= userdata
;
344 _cleanup_cap_free_charp_
char *t
= NULL
;
352 s
= t
= cap_to_text(c
->capabilities
, NULL
);
359 return sd_bus_message_append(reply
, "s", s
);
362 static int property_get_syscall_filter(
365 const char *interface
,
366 const char *property
,
367 sd_bus_message
*reply
,
369 sd_bus_error
*error
) {
371 ExecContext
*c
= userdata
;
372 _cleanup_strv_free_
char **l
= NULL
;
384 r
= sd_bus_message_open_container(reply
, 'r', "bas");
388 r
= sd_bus_message_append(reply
, "b", c
->syscall_whitelist
);
393 SET_FOREACH(id
, c
->syscall_filter
, i
) {
396 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
400 r
= strv_consume(&l
, name
);
408 r
= sd_bus_message_append_strv(reply
, l
);
412 return sd_bus_message_close_container(reply
);
415 static int property_get_syscall_archs(
418 const char *interface
,
419 const char *property
,
420 sd_bus_message
*reply
,
422 sd_bus_error
*error
) {
424 ExecContext
*c
= userdata
;
425 _cleanup_strv_free_
char **l
= NULL
;
438 SET_FOREACH(id
, c
->syscall_archs
, i
) {
441 name
= seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1);
445 r
= strv_extend(&l
, name
);
453 r
= sd_bus_message_append_strv(reply
, l
);
460 static int property_get_syscall_errno(
463 const char *interface
,
464 const char *property
,
465 sd_bus_message
*reply
,
467 sd_bus_error
*error
) {
469 ExecContext
*c
= userdata
;
475 return sd_bus_message_append(reply
, "i", (int32_t) c
->syscall_errno
);
478 static int property_get_selinux_context(
481 const char *interface
,
482 const char *property
,
483 sd_bus_message
*reply
,
485 sd_bus_error
*error
) {
487 ExecContext
*c
= userdata
;
493 return sd_bus_message_append(reply
, "(bs)", c
->selinux_context_ignore
, c
->selinux_context
);
496 static int property_get_apparmor_profile(
499 const char *interface
,
500 const char *property
,
501 sd_bus_message
*reply
,
503 sd_bus_error
*error
) {
505 ExecContext
*c
= userdata
;
511 return sd_bus_message_append(reply
, "(bs)", c
->apparmor_profile_ignore
, c
->apparmor_profile
);
514 static int property_get_smack_process_label(
517 const char *interface
,
518 const char *property
,
519 sd_bus_message
*reply
,
521 sd_bus_error
*error
) {
523 ExecContext
*c
= userdata
;
529 return sd_bus_message_append(reply
, "(bs)", c
->smack_process_label_ignore
, c
->smack_process_label
);
532 static int property_get_personality(
535 const char *interface
,
536 const char *property
,
537 sd_bus_message
*reply
,
539 sd_bus_error
*error
) {
541 ExecContext
*c
= userdata
;
547 return sd_bus_message_append(reply
, "s", personality_to_string(c
->personality
));
550 static int property_get_address_families(
553 const char *interface
,
554 const char *property
,
555 sd_bus_message
*reply
,
557 sd_bus_error
*error
) {
559 ExecContext
*c
= userdata
;
560 _cleanup_strv_free_
char **l
= NULL
;
569 r
= sd_bus_message_open_container(reply
, 'r', "bas");
573 r
= sd_bus_message_append(reply
, "b", c
->address_families_whitelist
);
577 SET_FOREACH(af
, c
->address_families
, i
) {
580 name
= af_to_name(PTR_TO_INT(af
));
584 r
= strv_extend(&l
, name
);
591 r
= sd_bus_message_append_strv(reply
, l
);
595 return sd_bus_message_close_container(reply
);
598 const sd_bus_vtable bus_exec_vtable
[] = {
599 SD_BUS_VTABLE_START(0),
600 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(ExecContext
, environment
), SD_BUS_VTABLE_PROPERTY_CONST
),
601 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
602 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode
, offsetof(ExecContext
, umask
), SD_BUS_VTABLE_PROPERTY_CONST
),
603 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CPU
]), SD_BUS_VTABLE_PROPERTY_CONST
),
604 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_FSIZE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
605 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_DATA
]), SD_BUS_VTABLE_PROPERTY_CONST
),
606 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_STACK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
607 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_CORE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
608 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RSS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
609 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NOFILE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
610 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_AS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
611 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NPROC
]), SD_BUS_VTABLE_PROPERTY_CONST
),
612 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MEMLOCK
]), SD_BUS_VTABLE_PROPERTY_CONST
),
613 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_LOCKS
]), SD_BUS_VTABLE_PROPERTY_CONST
),
614 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_SIGPENDING
]), SD_BUS_VTABLE_PROPERTY_CONST
),
615 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_MSGQUEUE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
616 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_NICE
]), SD_BUS_VTABLE_PROPERTY_CONST
),
617 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTPRIO
]), SD_BUS_VTABLE_PROPERTY_CONST
),
618 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit
, offsetof(ExecContext
, rlimit
[RLIMIT_RTTIME
]), SD_BUS_VTABLE_PROPERTY_CONST
),
619 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL
, offsetof(ExecContext
, working_directory
), SD_BUS_VTABLE_PROPERTY_CONST
),
620 SD_BUS_PROPERTY("RootDirectory", "s", NULL
, offsetof(ExecContext
, root_directory
), SD_BUS_VTABLE_PROPERTY_CONST
),
621 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
622 SD_BUS_PROPERTY("Nice", "i", property_get_nice
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
623 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
624 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
625 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
626 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
627 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
628 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool
, offsetof(ExecContext
, cpu_sched_reset_on_fork
), SD_BUS_VTABLE_PROPERTY_CONST
),
629 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool
, offsetof(ExecContext
, non_blocking
), SD_BUS_VTABLE_PROPERTY_CONST
),
630 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input
, offsetof(ExecContext
, std_input
), SD_BUS_VTABLE_PROPERTY_CONST
),
631 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output
, offsetof(ExecContext
, std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
632 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output
, offsetof(ExecContext
, std_error
), SD_BUS_VTABLE_PROPERTY_CONST
),
633 SD_BUS_PROPERTY("TTYPath", "s", NULL
, offsetof(ExecContext
, tty_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
634 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_reset
), SD_BUS_VTABLE_PROPERTY_CONST
),
635 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_vhangup
), SD_BUS_VTABLE_PROPERTY_CONST
),
636 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool
, offsetof(ExecContext
, tty_vt_disallocate
), SD_BUS_VTABLE_PROPERTY_CONST
),
637 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int
, offsetof(ExecContext
, syslog_priority
), SD_BUS_VTABLE_PROPERTY_CONST
),
638 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL
, offsetof(ExecContext
, syslog_identifier
), SD_BUS_VTABLE_PROPERTY_CONST
),
639 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool
, offsetof(ExecContext
, syslog_level_prefix
), SD_BUS_VTABLE_PROPERTY_CONST
),
640 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
641 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int
, offsetof(ExecContext
, secure_bits
), SD_BUS_VTABLE_PROPERTY_CONST
),
642 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
643 SD_BUS_PROPERTY("User", "s", NULL
, offsetof(ExecContext
, user
), SD_BUS_VTABLE_PROPERTY_CONST
),
644 SD_BUS_PROPERTY("Group", "s", NULL
, offsetof(ExecContext
, group
), SD_BUS_VTABLE_PROPERTY_CONST
),
645 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL
, offsetof(ExecContext
, supplementary_groups
), SD_BUS_VTABLE_PROPERTY_CONST
),
646 SD_BUS_PROPERTY("PAMName", "s", NULL
, offsetof(ExecContext
, pam_name
), SD_BUS_VTABLE_PROPERTY_CONST
),
647 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL
, offsetof(ExecContext
, read_write_dirs
), SD_BUS_VTABLE_PROPERTY_CONST
),
648 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL
, offsetof(ExecContext
, read_only_dirs
), SD_BUS_VTABLE_PROPERTY_CONST
),
649 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL
, offsetof(ExecContext
, inaccessible_dirs
), SD_BUS_VTABLE_PROPERTY_CONST
),
650 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong
, offsetof(ExecContext
, mount_flags
), SD_BUS_VTABLE_PROPERTY_CONST
),
651 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool
, offsetof(ExecContext
, private_tmp
), SD_BUS_VTABLE_PROPERTY_CONST
),
652 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool
, offsetof(ExecContext
, private_network
), SD_BUS_VTABLE_PROPERTY_CONST
),
653 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool
, offsetof(ExecContext
, private_devices
), SD_BUS_VTABLE_PROPERTY_CONST
),
654 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home
, offsetof(ExecContext
, protect_home
), SD_BUS_VTABLE_PROPERTY_CONST
),
655 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system
, offsetof(ExecContext
, protect_system
), SD_BUS_VTABLE_PROPERTY_CONST
),
656 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool
, offsetof(ExecContext
, same_pgrp
), SD_BUS_VTABLE_PROPERTY_CONST
),
657 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL
, offsetof(ExecContext
, utmp_id
), SD_BUS_VTABLE_PROPERTY_CONST
),
658 SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode
, offsetof(ExecContext
, utmp_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
659 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
660 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
661 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
662 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool
, offsetof(ExecContext
, ignore_sigpipe
), SD_BUS_VTABLE_PROPERTY_CONST
),
663 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool
, offsetof(ExecContext
, no_new_privileges
), SD_BUS_VTABLE_PROPERTY_CONST
),
664 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
665 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
666 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
667 SD_BUS_PROPERTY("Personality", "s", property_get_personality
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
668 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
669 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode
, offsetof(ExecContext
, runtime_directory_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
670 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL
, offsetof(ExecContext
, runtime_directory
), SD_BUS_VTABLE_PROPERTY_CONST
),
674 static int append_exec_command(sd_bus_message
*reply
, ExecCommand
*c
) {
683 r
= sd_bus_message_open_container(reply
, 'r', "sasbttttuii");
687 r
= sd_bus_message_append(reply
, "s", c
->path
);
691 r
= sd_bus_message_append_strv(reply
, c
->argv
);
695 r
= sd_bus_message_append(reply
, "bttttuii",
697 c
->exec_status
.start_timestamp
.realtime
,
698 c
->exec_status
.start_timestamp
.monotonic
,
699 c
->exec_status
.exit_timestamp
.realtime
,
700 c
->exec_status
.exit_timestamp
.monotonic
,
701 (uint32_t) c
->exec_status
.pid
,
702 (int32_t) c
->exec_status
.code
,
703 (int32_t) c
->exec_status
.status
);
707 return sd_bus_message_close_container(reply
);
710 int bus_property_get_exec_command(
713 const char *interface
,
714 const char *property
,
715 sd_bus_message
*reply
,
717 sd_bus_error
*ret_error
) {
719 ExecCommand
*c
= (ExecCommand
*) userdata
;
725 r
= sd_bus_message_open_container(reply
, 'a', "(sasbttttuii)");
729 r
= append_exec_command(reply
, c
);
733 return sd_bus_message_close_container(reply
);
736 int bus_property_get_exec_command_list(
739 const char *interface
,
740 const char *property
,
741 sd_bus_message
*reply
,
743 sd_bus_error
*ret_error
) {
745 ExecCommand
*c
= *(ExecCommand
**) userdata
;
751 r
= sd_bus_message_open_container(reply
, 'a', "(sasbttttuii)");
755 LIST_FOREACH(command
, c
, c
) {
756 r
= append_exec_command(reply
, c
);
761 return sd_bus_message_close_container(reply
);
764 int bus_exec_context_set_transient_property(
768 sd_bus_message
*message
,
769 UnitSetPropertiesMode mode
,
770 sd_bus_error
*error
) {
779 if (streq(name
, "User")) {
782 r
= sd_bus_message_read(message
, "s", &uu
);
786 if (mode
!= UNIT_CHECK
) {
789 c
->user
= mfree(c
->user
);
801 unit_write_drop_in_private_format(u
, mode
, name
, "User=%s\n", uu
);
806 } else if (streq(name
, "Group")) {
809 r
= sd_bus_message_read(message
, "s", &gg
);
813 if (mode
!= UNIT_CHECK
) {
816 c
->group
= mfree(c
->group
);
828 unit_write_drop_in_private_format(u
, mode
, name
, "Group=%s\n", gg
);
833 } else if (streq(name
, "Nice")) {
836 r
= sd_bus_message_read(message
, "i", &n
);
840 if (n
< PRIO_MIN
|| n
>= PRIO_MAX
)
841 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Nice value out of range");
843 if (mode
!= UNIT_CHECK
) {
845 unit_write_drop_in_private_format(u
, mode
, name
, "Nice=%i\n", n
);
850 } else if (streq(name
, "TTYPath")) {
853 r
= sd_bus_message_read(message
, "s", &tty
);
857 if (!path_is_absolute(tty
))
858 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "TTY device not absolute path");
860 if (mode
!= UNIT_CHECK
) {
870 unit_write_drop_in_private_format(u
, mode
, name
, "TTYPath=%s\n", tty
);
875 } else if (streq(name
, "StandardInput")) {
879 r
= sd_bus_message_read(message
, "s", &s
);
883 p
= exec_input_from_string(s
);
885 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard input name");
887 if (mode
!= UNIT_CHECK
) {
890 unit_write_drop_in_private_format(u
, mode
, name
, "StandardInput=%s\n", exec_input_to_string(p
));
896 } else if (streq(name
, "StandardOutput")) {
900 r
= sd_bus_message_read(message
, "s", &s
);
904 p
= exec_output_from_string(s
);
906 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard output name");
908 if (mode
!= UNIT_CHECK
) {
911 unit_write_drop_in_private_format(u
, mode
, name
, "StandardOutput=%s\n", exec_output_to_string(p
));
916 } else if (streq(name
, "StandardError")) {
920 r
= sd_bus_message_read(message
, "s", &s
);
924 p
= exec_output_from_string(s
);
926 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid standard error name");
928 if (mode
!= UNIT_CHECK
) {
931 unit_write_drop_in_private_format(u
, mode
, name
, "StandardError=%s\n", exec_output_to_string(p
));
936 } else if (STR_IN_SET(name
,
937 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset",
938 "PrivateTmp", "PrivateDevices", "PrivateNetwork",
939 "NoNewPrivileges")) {
942 r
= sd_bus_message_read(message
, "b", &b
);
946 if (mode
!= UNIT_CHECK
) {
947 if (streq(name
, "IgnoreSIGPIPE"))
948 c
->ignore_sigpipe
= b
;
949 else if (streq(name
, "TTYVHangup"))
951 else if (streq(name
, "TTYReset"))
953 else if (streq(name
, "PrivateTmp"))
955 else if (streq(name
, "PrivateDevices"))
956 c
->private_devices
= b
;
957 else if (streq(name
, "PrivateNetwork"))
958 c
->private_network
= b
;
959 else if (streq(name
, "NoNewPrivileges"))
960 c
->no_new_privileges
= b
;
962 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%s\n", name
, yes_no(b
));
967 } else if (streq(name
, "UtmpIdentifier")) {
970 r
= sd_bus_message_read(message
, "s", &id
);
974 if (mode
!= UNIT_CHECK
) {
976 c
->utmp_id
= mfree(c
->utmp_id
);
977 else if (free_and_strdup(&c
->utmp_id
, id
) < 0)
980 unit_write_drop_in_private_format(u
, mode
, name
, "UtmpIdentifier=%s\n", strempty(id
));
985 } else if (streq(name
, "UtmpMode")) {
989 r
= sd_bus_message_read(message
, "s", &s
);
993 m
= exec_utmp_mode_from_string(s
);
995 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid utmp mode");
997 if (mode
!= UNIT_CHECK
) {
1000 unit_write_drop_in_private_format(u
, mode
, name
, "UtmpMode=%s\n", exec_utmp_mode_to_string(m
));
1005 } else if (streq(name
, "PAMName")) {
1008 r
= sd_bus_message_read(message
, "s", &n
);
1012 if (mode
!= UNIT_CHECK
) {
1014 c
->pam_name
= mfree(c
->pam_name
);
1015 else if (free_and_strdup(&c
->pam_name
, n
) < 0)
1018 unit_write_drop_in_private_format(u
, mode
, name
, "PAMName=%s\n", strempty(n
));
1023 } else if (streq(name
, "Environment")) {
1025 _cleanup_strv_free_
char **l
= NULL
;
1027 r
= sd_bus_message_read_strv(message
, &l
);
1031 if (!strv_env_is_valid(l
))
1032 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment block.");
1034 if (mode
!= UNIT_CHECK
) {
1035 _cleanup_free_
char *joined
= NULL
;
1038 e
= strv_env_merge(2, c
->environment
, l
);
1042 strv_free(c
->environment
);
1045 joined
= strv_join_quoted(c
->environment
);
1049 unit_write_drop_in_private_format(u
, mode
, name
, "Environment=%s\n", joined
);
1054 } else if (rlimit_from_string(name
) >= 0) {
1058 r
= sd_bus_message_read(message
, "t", &rl
);
1062 if (rl
== (uint64_t) -1)
1067 if ((uint64_t) x
!= rl
)
1071 if (mode
!= UNIT_CHECK
) {
1074 z
= rlimit_from_string(name
);
1076 if (!c
->rlimit
[z
]) {
1077 c
->rlimit
[z
] = new(struct rlimit
, 1);
1082 c
->rlimit
[z
]->rlim_cur
= c
->rlimit
[z
]->rlim_max
= x
;
1084 if (x
== RLIM_INFINITY
)
1085 unit_write_drop_in_private_format(u
, mode
, name
, "%s=infinity\n", name
);
1087 unit_write_drop_in_private_format(u
, mode
, name
, "%s=%" PRIu64
"\n", name
, rl
);