]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/dbus-execute.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / core / dbus-execute.c
index 6d3cc5d35be9953dcddc653f7f0dbb6c046079e6..f22bf4a371c54eb1c8125bfa9c4a8f00823c930a 100644 (file)
@@ -1,9 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
-/***
-  This file is part of systemd.
-
-  Copyright 2010 Lennart Poettering
-***/
 
 #include <sys/mount.h>
 #include <sys/prctl.h>
@@ -32,7 +27,7 @@
 #include "ioprio.h"
 #include "journal-util.h"
 #include "missing.h"
-#include "mount-util.h"
+#include "mountpoint-util.h"
 #include "namespace.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -60,6 +55,9 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsig
 static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
 static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_CLASS);
 static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_DATA);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI);
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC);
 
 static int property_get_environment_files(
                 sd_bus *bus,
@@ -249,21 +247,6 @@ static int property_get_timer_slack_nsec(
         return sd_bus_message_append(reply, "t", u);
 }
 
-static int property_get_empty_string(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        assert(bus);
-        assert(reply);
-
-        return sd_bus_message_append(reply, "s", NULL);
-}
-
 static int property_get_syscall_filter(
                 sd_bus *bus,
                 const char *path,
@@ -508,42 +491,6 @@ static int property_get_working_directory(
         return sd_bus_message_append(reply, "s", wd);
 }
 
-static int property_get_syslog_level(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        int *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "i", LOG_PRI(*s));
-}
-
-static int property_get_syslog_facility(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        int *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "i", LOG_FAC(*s));
-}
-
 static int property_get_stdio_fdname(
                 sd_bus *bus,
                 const char *path,
@@ -611,7 +558,7 @@ static int property_get_bind_paths(
         assert(property);
         assert(reply);
 
-        ro = !!strstr(property, "ReadOnly");
+        ro = strstr(property, "ReadOnly");
 
         r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
         if (r < 0)
@@ -771,6 +718,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_rate_limit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_rate_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -792,6 +741,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("PrivateMounts", "b", bus_property_get_bool, offsetof(ExecContext, private_mounts), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ProtectSystem", "s", property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -827,6 +777,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ProtectHostname", "b", bus_property_get_bool, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
 
         /* Obsolete/redundant properties: */
         SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
@@ -983,7 +934,7 @@ int bus_set_transient_exec_command(
 
                         c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
 
-                        path_kill_slashes(c->path);
+                        path_simplify(c->path, false);
                         exec_command_append_list(exec_command, c);
                 }
 
@@ -1067,20 +1018,17 @@ static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi3
 #if HAVE_SECCOMP
 static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, errno_is_valid);
 #endif
-static BUS_DEFINE_SET_TRANSIENT_IS_VALID(sched_priority, "i", int32_t, int, "%" PRIi32, sched_priority_is_valid);
-static BUS_DEFINE_SET_TRANSIENT_IS_VALID(nice, "i", int32_t, int, "%" PRIi32, nice_is_valid);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
-static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, parse_protect_system_or_bool);
-static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, parse_protect_home_or_bool);
+static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_from_string);
+static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
 static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
 static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
 static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc);
-static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(sched_policy, "i", int32_t, int, "%" PRIi32, sched_policy_to_string_alloc_with_check);
-static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flag_to_string_many_with_check);
+static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string);
 static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flags_to_string_with_check);
 
 int bus_exec_context_set_transient_property(
@@ -1122,15 +1070,15 @@ int bus_exec_context_set_transient_property(
         if (streq(name, "LogLevelMax"))
                 return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
 
-        if (streq(name, "CPUSchedulingPriority"))
-                return bus_set_transient_sched_priority(u, name, &c->cpu_sched_priority, message, flags, error);
+        if (streq(name, "LogRateLimitIntervalUSec"))
+                return bus_set_transient_usec(u, name, &c->log_rate_limit_interval_usec, message, flags, error);
+
+        if (streq(name, "LogRateLimitBurst"))
+                return bus_set_transient_unsigned(u, name, &c->log_rate_limit_burst, message, flags, error);
 
         if (streq(name, "Personality"))
                 return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
 
-        if (streq(name, "Nice"))
-                return bus_set_transient_nice(u, name, &c->nice, message, flags, error);
-
         if (streq(name, "StandardInput"))
                 return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
 
@@ -1158,6 +1106,9 @@ int bus_exec_context_set_transient_property(
         if (streq(name, "PrivateDevices"))
                 return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
 
+        if (streq(name, "PrivateMounts"))
+                return bus_set_transient_bool(u, name, &c->private_mounts, message, flags, error);
+
         if (streq(name, "PrivateNetwork"))
                 return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
 
@@ -1203,6 +1154,9 @@ int bus_exec_context_set_transient_property(
         if (streq(name, "LockPersonality"))
                 return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
 
+        if (streq(name, "ProtectHostname"))
+                return bus_set_transient_bool(u, name, &c->protect_hostname, message, flags, error);
+
         if (streq(name, "UtmpIdentifier"))
                 return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
 
@@ -1257,9 +1211,6 @@ int bus_exec_context_set_transient_property(
         if (streq(name, "AmbientCapabilities"))
                 return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
 
-        if (streq(name, "CPUSchedulingPolicy"))
-                return bus_set_transient_sched_policy(u, name, &c->cpu_sched_policy, message, flags, error);
-
         if (streq(name, "RestrictNamespaces"))
                 return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
 
@@ -1570,8 +1521,8 @@ int bus_exec_context_set_transient_property(
                                 int af;
 
                                 af = af_from_name(*s);
-                                if (af <= 0)
-                                        return -EINVAL;
+                                if (af < 0)
+                                        return af;
 
                                 if (!invert == c->address_families_whitelist) {
                                         r = set_put(c->address_families, INT_TO_PTR(af));
@@ -1658,6 +1609,72 @@ int bus_exec_context_set_transient_property(
 
                 return 1;
 
+        } else if (streq(name, "Nice")) {
+                int32_t q;
+
+                r = sd_bus_message_read(message, "i", &q);
+                if (r < 0)
+                        return r;
+
+                if (!nice_is_valid(q))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Nice value: %i", q);
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->nice = q;
+                        c->nice_set = true;
+
+                        unit_write_settingf(u, flags, name, "Nice=%i", q);
+                }
+
+                return 1;
+
+        } else if (streq(name, "CPUSchedulingPolicy")) {
+                int32_t q;
+
+                r = sd_bus_message_read(message, "i", &q);
+                if (r < 0)
+                        return r;
+
+                if (!sched_policy_is_valid(q))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy: %i", q);
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        _cleanup_free_ char *s = NULL;
+
+                        r = sched_policy_to_string_alloc(q, &s);
+                        if (r < 0)
+                                return r;
+
+                        c->cpu_sched_policy = q;
+                        c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(q), sched_get_priority_max(q));
+                        c->cpu_sched_set = true;
+
+                        unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", s);
+                }
+
+                return 1;
+
+        } else if (streq(name, "CPUSchedulingPriority")) {
+                int32_t p, min, max;
+
+                r = sd_bus_message_read(message, "i", &p);
+                if (r < 0)
+                        return r;
+
+                min = sched_get_priority_min(c->cpu_sched_policy);
+                max = sched_get_priority_max(c->cpu_sched_policy);
+                if (p < min || p > max)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority: %i", p);
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->cpu_sched_priority = p;
+                        c->cpu_sched_set = true;
+
+                        unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", p);
+                }
+
+                return 1;
+
         } else if (streq(name, "IOSchedulingClass")) {
                 int32_t q;
 
@@ -1780,7 +1797,10 @@ int bus_exec_context_set_transient_property(
 
                 return 1;
 
-        } else if (STR_IN_SET(name, "StandardInputFile", "StandardOutputFile", "StandardErrorFile")) {
+        } else if (STR_IN_SET(name,
+                              "StandardInputFile",
+                              "StandardOutputFile", "StandardOutputFileToAppend",
+                              "StandardErrorFile", "StandardErrorFileToAppend")) {
                 const char *s;
 
                 r = sd_bus_message_read(message, "s", &s);
@@ -1804,23 +1824,34 @@ int bus_exec_context_set_transient_property(
                                 c->std_input = EXEC_INPUT_FILE;
                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
 
-                        } else if (streq(name, "StandardOutputFile")) {
+                        } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend")) {
                                 r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s));
                                 if (r < 0)
                                         return r;
 
-                                c->std_output = EXEC_OUTPUT_FILE;
-                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
-
+                                if (streq(name, "StandardOutputFile")) {
+                                        c->std_output = EXEC_OUTPUT_FILE;
+                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
+                                } else {
+                                        assert(streq(name, "StandardOutputFileToAppend"));
+                                        c->std_output = EXEC_OUTPUT_FILE_APPEND;
+                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s);
+                                }
                         } else {
-                                assert(streq(name, "StandardErrorFile"));
+                                assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend"));
 
                                 r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s));
                                 if (r < 0)
                                         return r;
 
-                                c->std_error = EXEC_OUTPUT_FILE;
-                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
+                                if (streq(name, "StandardErrorFile")) {
+                                        c->std_error = EXEC_OUTPUT_FILE;
+                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
+                                } else {
+                                        assert(streq(name, "StandardErrorFileToAppend"));
+                                        c->std_error = EXEC_OUTPUT_FILE_APPEND;
+                                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s);
+                                }
                         }
                 }
 
@@ -2099,7 +2130,7 @@ int bus_exec_context_set_transient_property(
                         if (!path_is_absolute(i + offset))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
 
-                        path_kill_slashes(i + offset);
+                        path_simplify(i + offset, false);
                 }
 
                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {