/* SPDX-License-Identifier: LGPL-2.1+ */
/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
- Copyright 2012 Holger Hans Peter Freyther
+ Copyright © 2012 Holger Hans Peter Freyther
***/
#include <errno.h>
#include "unit-name.h"
#include "unit-printf.h"
#include "user-util.h"
-#include "utf8.h"
#include "web-util.h"
+static int supported_socket_protocol_from_string(const char *s) {
+ int r;
+
+ if (isempty(s))
+ return IPPROTO_IP;
+
+ r = socket_protocol_from_name(s);
+ if (r < 0)
+ return -EINVAL;
+ if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP))
+ return -EPROTONOSUPPORT;
+
+ return r;
+}
+
+DEFINE_CONFIG_PARSE(config_parse_socket_protocol, supported_socket_protocol_from_string, "Failed to parse socket protocol");
+DEFINE_CONFIG_PARSE(config_parse_exec_secure_bits, secure_bits_from_string, "Failed to parse secure bits");
DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_home, protect_home_or_bool, ProtectHome, "Failed to parse protect home value");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_system, protect_system_or_bool, ProtectSystem, "Failed to parse protect system value");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_socket_bind, socket_address_bind_ipv6_only_or_bool, SocketAddressBindIPv6Only, "Failed to parse bind IPv6 only value");
+DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_ip_tos, ip_tos, int, -1, "Failed to parse IP TOS value");
+DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint64_t, "Invalid block IO weight");
+DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight");
+DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares");
+DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag");
int config_parse_unit_deps(
const char *unit,
return 0;
}
- if (!utf8_is_valid(k)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
- }
-
- if (!path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Symlink path is not absolute: %s", k);
+ r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
-
- path_kill_slashes(k);
r = strv_push(x, k);
if (r < 0)
return log_oom();
if (ltype != SOCKET_SOCKET) {
+ _cleanup_free_ char *k = NULL;
- p->type = ltype;
- r = unit_full_printf(UNIT(s), rvalue, &p->path);
+ r = unit_full_printf(UNIT(s), rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
return 0;
}
- path_kill_slashes(p->path);
+ r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
+ return 0;
+
+ free_and_replace(p->path, k);
+ p->type = ltype;
} else if (streq(lvalue, "ListenNetlink")) {
_cleanup_free_ char *k = NULL;
- p->type = SOCKET_SOCKET;
r = unit_full_printf(UNIT(s), rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
return 0;
}
+ p->type = SOCKET_SOCKET;
+
} else {
_cleanup_free_ char *k = NULL;
- p->type = SOCKET_SOCKET;
r = unit_full_printf(UNIT(s), rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Address family not supported, ignoring: %s", rvalue);
return 0;
}
+
+ p->type = SOCKET_SOCKET;
}
p->fd = -1;
return 0;
}
-int config_parse_socket_protocol(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
- Socket *s;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- s = SOCKET(data);
-
- r = socket_protocol_from_name(rvalue);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid socket protocol '%s', ignoring: %m", rvalue);
- return 0;
- } else if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue);
- return 0;
- }
-
- s->socket_protocol = r;
-
- return 0;
-}
-
-int config_parse_socket_bind(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- Socket *s;
- SocketAddressBindIPv6Only b;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- s = SOCKET(data);
-
- b = parse_socket_address_bind_ipv6_only_or_bool(rvalue);
- if (b < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue);
- return 0;
- }
-
- s->bind_ipv6_only = b;
-
- return 0;
-}
-
int config_parse_exec_nice(
const char *unit,
const char *filename,
n[nlen] = NULL;
}
- path_kill_slashes(path);
+ path_simplify(path, false);
while (!isempty(p)) {
_cleanup_free_ char *word = NULL, *resolved = NULL;
return 0;
}
-DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
-
int config_parse_socket_bindtodevice(
const char* unit,
const char *filename,
return 0;
}
- free_and_strdup(&s->bind_to_device, rvalue);
+ if (free_and_strdup(&s->bind_to_device, rvalue) < 0)
+ return log_oom();
return 0;
}
resolved = mfree(resolved);
else if (!fdname_is_valid(resolved)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name: %s", resolved);
- return -EINVAL;
+ return -ENOEXEC;
}
free_and_replace(c->stdio_fdname[STDIN_FILENO], resolved);
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s': %m", n);
- if (!path_is_absolute(resolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires an absolute path name: %s", resolved);
- return -EINVAL;
- }
-
- if (!path_is_normalized(resolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires a normalized path name: %s", resolved);
- return -EINVAL;
- }
+ r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE | PATH_CHECK_FATAL, unit, filename, line, lvalue);
+ if (r < 0)
+ return -ENOEXEC;
free_and_replace(c->stdio_file[STDIN_FILENO], resolved);
resolved = mfree(resolved);
else if (!fdname_is_valid(resolved)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid file descriptor name: %s", resolved);
- return -EINVAL;
+ return -ENOEXEC;
}
eo = EXEC_OUTPUT_NAMED_FD;
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", n);
- if (!path_is_absolute(resolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires an absolute path name: %s", resolved);
- return -EINVAL;
- }
-
- if (!path_is_normalized(resolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires a normalized path name, ignoring: %s", resolved);
- return -EINVAL;
- }
+ r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE | PATH_CHECK_FATAL, unit, filename, line, lvalue);
+ if (r < 0)
+ return -ENOEXEC;
eo = EXEC_OUTPUT_FILE;
assert(rvalue);
assert(data);
+ if (isempty(rvalue)) {
+ c->cpu_sched_set = false;
+ c->cpu_sched_policy = SCHED_OTHER;
+ c->cpu_sched_priority = 0;
+ return 0;
+ }
+
x = sched_policy_from_string(rvalue);
if (x < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse CPU scheduling policy, ignoring: %s", rvalue);
return 0;
}
-int config_parse_exec_secure_bits(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ExecContext *c = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (isempty(rvalue)) {
- /* An empty assignment resets the field */
- c->secure_bits = 0;
- return 0;
- }
-
- r = secure_bits_from_string(rvalue);
- if (r < 0) {
- log_syntax(unit, LOG_WARNING, filename, line, r,
- "Failed to parse secure bits, ignoring: %s", rvalue);
- return 0;
- }
-
- c->secure_bits = r;
-
- return 0;
-}
-
int config_parse_capability_set(
const char *unit,
const char *filename,
return 0;
}
-#if HAVE_SYSV_COMPAT
-int config_parse_sysv_priority(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- int *priority = data;
- int i, r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = safe_atoi(rvalue, &i);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse SysV start priority, ignoring: %s", rvalue);
- return 0;
- }
- if (i < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SysV start priority, ignoring: %s", rvalue);
- return 0;
- }
-
- *priority = (int) i;
- return 0;
-}
-#endif
-
-DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
-
-int config_parse_exec_mount_flags(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ExecContext *c = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = mount_propagation_flags_from_string(rvalue, &c->mount_flags);
- if (r < 0)
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse mount flag %s, ignoring: %m", rvalue);
-
- return 0;
-}
-
int config_parse_exec_selinux_context(
const char *unit,
const char *filename,
return 0;
}
- path_kill_slashes(k);
-
- if (!path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Path is not absolute, ignoring: %s", k);
+ r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
s = new0(PathSpec, 1);
if (!s)
assert(rvalue);
assert(s);
- /* This is called for three cases: TimeoutSec=, TimeoutStopSec= and TimeoutStartSec=. */
+ /* This is called for two cases: TimeoutSec= and TimeoutStartSec=. */
- r = parse_sec(rvalue, &usec);
+ /* Traditionally, these options accepted 0 to disable the timeouts. However, a timeout of 0 suggests it happens
+ * immediately, hence fix this to become USEC_INFINITY instead. This is in-line with how we internally handle
+ * all other timeouts. */
+ r = parse_sec_fix_0(rvalue, &usec);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue);
return 0;
}
- /* Traditionally, these options accepted 0 to disable the timeouts. However, a timeout of 0 suggests it happens
- * immediately, hence fix this to become USEC_INFINITY instead. This is in-line with how we internally handle
- * all other timeouts. */
- if (usec <= 0)
- usec = USEC_INFINITY;
-
- if (!streq(lvalue, "TimeoutStopSec")) {
- s->start_timeout_defined = true;
- s->timeout_start_usec = usec;
- }
+ s->start_timeout_defined = true;
+ s->timeout_start_usec = usec;
- if (!streq(lvalue, "TimeoutStartSec"))
+ if (streq(lvalue, "TimeoutSec"))
s->timeout_stop_usec = usec;
return 0;
assert(c);
assert(u);
+ if (isempty(rvalue)) {
+ c->working_directory_home = false;
+ c->working_directory = mfree(c->working_directory);
+ return 0;
+ }
+
if (rvalue[0] == '-') {
missing_ok = true;
rvalue++;
return missing_ok ? 0 : -ENOEXEC;
}
- path_kill_slashes(k);
-
- if (!utf8_is_valid(k)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return missing_ok ? 0 : -ENOEXEC;
- }
-
- if (!path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Working directory path '%s' is not absolute%s.",
- rvalue, missing_ok ? ", ignoring" : "");
+ r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE | (missing_ok ? 0 : PATH_CHECK_FATAL), unit, filename, line, lvalue);
+ if (r < 0)
return missing_ok ? 0 : -ENOEXEC;
- }
c->working_directory_home = false;
free_and_replace(c->working_directory, k);
return 0;
}
- if (!path_is_absolute(n[0] == '-' ? n + 1 : n)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Path '%s' is not absolute, ignoring.", n);
+ r = path_simplify_and_warn(n[0] == '-' ? n + 1 : n, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
- r = strv_extend(env, n);
+ r = strv_push(env, n);
if (r < 0)
return log_oom();
+ n = NULL;
+
return 0;
}
}
}
-int config_parse_ip_tos(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- int *ip_tos = data, x;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- x = ip_tos_from_string(rvalue);
- if (x < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IP TOS value, ignoring: %s", rvalue);
- return 0;
- }
-
- *ip_tos = x;
- return 0;
-}
-
int config_parse_unit_condition_path(
const char *unit,
const char *filename,
return 0;
}
- if (!path_is_absolute(p)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Path in condition not absolute, ignoring: %s", p);
+ r = path_simplify_and_warn(p, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
c = condition_new(t, p, trigger, negate);
if (!c)
return 0;
}
-DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier");
-
int config_parse_unit_requires_mounts_for(
const char *unit,
const char *filename,
return 0;
}
- if (!utf8_is_valid(word)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- continue;
- }
-
r = unit_full_printf(u, word, &resolved);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", word);
continue;
}
+ r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
+ continue;
+
r = unit_require_mounts_for(u, resolved, UNIT_DEPENDENCY_FILE);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount '%s', ignoring: %m", resolved);
return 0;
}
-DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy");
-
-int config_parse_cpu_weight(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint64_t *weight = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- r = cg_weight_parse(rvalue, weight);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU weight '%s', ignoring: %m", rvalue);
- return 0;
- }
-
- return 0;
-}
-
-int config_parse_cpu_shares(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint64_t *shares = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- r = cg_cpu_shares_parse(rvalue, shares);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU shares '%s', ignoring: %m", rvalue);
- return 0;
- }
-
- return 0;
-}
-
int config_parse_cpu_quota(
const char *unit,
const char *filename,
return 0;
}
- if (!is_deviceallow_pattern(resolved) &&
- !path_startswith(resolved, "/run/systemd/inaccessible/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
- return 0;
+ if (!startswith(resolved, "block-") && !startswith(resolved, "char-")) {
+
+ r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
+ if (r < 0)
+ return 0;
+
+ if (!valid_device_node_path(resolved)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
+ return 0;
+ }
}
if (!isempty(p) && !in_charset(p, "rwm")) {
return 0;
}
-int config_parse_io_weight(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint64_t *weight = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- r = cg_weight_parse(rvalue, weight);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid IO weight '%s', ignoring.", rvalue);
- return 0;
- }
-
- return 0;
-}
-
int config_parse_io_device_weight(
const char *unit,
const char *filename,
return 0;
}
- if (!path_startswith(resolved, "/dev") &&
- !path_startswith(resolved, "/run/systemd/inaccessible/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
+ r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
r = cg_weight_parse(p, &u);
if (r < 0) {
return 0;
}
- if (!path_startswith(resolved, "/dev") &&
- !path_startswith(resolved, "/run/systemd/inaccessible/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
+ r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
- if (streq("infinity", p)) {
+ if (streq("infinity", p))
num = CGROUP_LIMIT_MAX;
- } else {
+ else {
r = parse_size(p, 1000, &num);
if (r < 0 || num <= 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid IO limit '%s', ignoring.", p);
return 0;
}
-int config_parse_blockio_weight(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint64_t *weight = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- r = cg_blkio_weight_parse(rvalue, weight);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid block IO weight '%s', ignoring: %m", rvalue);
- return 0;
- }
-
- return 0;
-}
-
int config_parse_blockio_device_weight(
const char *unit,
const char *filename,
return 0;
}
- if (!path_startswith(resolved, "/dev") &&
- !path_startswith(resolved, "/run/systemd/inaccessible/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", resolved);
+ r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
r = cg_blkio_weight_parse(p, &u);
if (r < 0) {
return 0;
}
- if (!path_startswith(resolved, "/dev") &&
- !path_startswith(resolved, "/run/systemd/inaccessible/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
+ r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
+ if (r < 0)
return 0;
- }
r = parse_size(p, 1000, &bytes);
if (r < 0 || bytes <= 0) {
return 0;
}
-DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode");
-
int config_parse_job_mode_isolate(
const char *unit,
const char *filename,
return 0;
}
-DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode");
-
int config_parse_exec_directories(
const char *unit,
const char *filename,
continue;
}
- if (!path_is_normalized(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path is not normalized, ignoring assignment: %s", lvalue, rvalue);
- continue;
- }
-
- if (path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path is absolute, ignoring assignment: %s", lvalue, rvalue);
+ r = path_simplify_and_warn(k, PATH_CHECK_RELATIVE, unit, filename, line, lvalue);
+ if (r < 0)
continue;
- }
if (path_startswith(k, "private")) {
log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path can't be 'private', ingoring assignment: %s", lvalue, rvalue);
+ "%s= path can't be 'private', ingoring assignment: %s", lvalue, word);
continue;
}
return 0;
}
- if (!utf8_is_valid(word)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
- continue;
- }
-
w = word;
if (startswith(w, "-")) {
ignore_enoent = true;
continue;
}
- if (!path_is_absolute(resolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", resolved);
+ r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
continue;
- }
-
- path_kill_slashes(resolved);
joined = strjoin(ignore_enoent ? "-" : "",
shall_prefix ? "+" : "",
continue;
}
- if (!path_is_absolute(resolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", resolved);
+ r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
continue;
- }
-
- path_kill_slashes(resolved);
r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, w);
if (r == -ENOMEM)
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s: %s", lvalue, rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, rvalue);
return 0;
}
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to resolved unit specifiers in \"%s\", ignoring: %m", source);
- return 0;
+ continue;
}
s = sresolved;
s++;
}
- if (!utf8_is_valid(s)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, s);
- return 0;
- }
- if (!path_is_absolute(s)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute source path, ignoring: %s", s);
- return 0;
- }
-
- path_kill_slashes(s);
+ r = path_simplify_and_warn(s, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
+ continue;
/* Optionally, the destination is specified. */
if (p && p[-1] == ':') {
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s: %s", lvalue, rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, rvalue);
return 0;
}
if (r == 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Missing argument after ':': %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Missing argument after ':', ignoring: %s", s);
+ continue;
}
r = unit_full_printf(u, destination, &dresolved);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to resolved specifiers in \"%s\", ignoring: %m", destination);
- return 0;
+ continue;
}
- if (!utf8_is_valid(dresolved)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, dresolved);
- return 0;
- }
- if (!path_is_absolute(dresolved)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute destination path, ignoring: %s", dresolved);
- return 0;
- }
+ r = path_simplify_and_warn(dresolved, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
+ if (r < 0)
+ continue;
- d = path_kill_slashes(dresolved);
+ d = dresolved;
/* Optionally, there's also a short option string specified */
if (p && p[-1] == ':') {
rbind = false;
else {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid option string, ignoring setting: %s", options);
- return 0;
+ continue;
}
}
} else
return 0;
}
-int config_parse_no_new_privileges(
- const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ExecContext *c = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = parse_boolean(rvalue);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse boolean value, ignoring: %s", rvalue);
- return 0;
- }
-
- c->no_new_privileges = r;
-
- return 0;
-}
-
-int config_parse_protect_home(
- const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ExecContext *c = data;
- ProtectHome h;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- /* Our enum shall be a superset of booleans, hence first try
- * to parse as boolean, and then as enum */
-
- h = parse_protect_home_or_bool(rvalue);
- if (h < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue);
- return 0;
- }
-
- c->protect_home = h;
-
- return 0;
-}
-
-int config_parse_protect_system(
- const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ExecContext *c = data;
- ProtectSystem s;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- s = parse_protect_system_or_bool(rvalue);
- if (s < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue);
- return 0;
- }
-
- c->protect_system = s;
-
- return 0;
-}
-
-DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode");
-
int config_parse_job_timeout_sec(
const char* unit,
const char *filename,
if (c++ >= FOLLOW_MAX)
return -ELOOP;
- path_kill_slashes(*filename);
+ path_simplify(*filename, false);
/* Add the file name we are currently looking at to
* the names of this unit, but only if it is a valid
if (r < 0)
return r;
- free(*filename);
- *filename = target;
+ free_and_replace(*filename, target);
}
f = fdopen(fd, "re");
const ConfigParserCallback callback;
const char *rvalue;
} table[] = {
-#if !HAVE_SYSV_COMPAT || !HAVE_SECCOMP || !HAVE_PAM || !HAVE_SELINUX || !ENABLE_SMACK || !HAVE_APPARMOR
{ config_parse_warn_compat, "NOTSUPPORTED" },
-#endif
{ config_parse_int, "INTEGER" },
{ config_parse_unsigned, "UNSIGNED" },
{ config_parse_iec_size, "SIZE" },
{ config_parse_exec, "PATH [ARGUMENT [...]]" },
{ config_parse_service_type, "SERVICETYPE" },
{ config_parse_service_restart, "SERVICERESTART" },
-#if HAVE_SYSV_COMPAT
- { config_parse_sysv_priority, "SYSVPRIORITY" },
-#endif
{ config_parse_kill_mode, "KILLMODE" },
{ config_parse_signal, "SIGNAL" },
{ config_parse_socket_listen, "SOCKET [...]" },
{ config_parse_restrict_namespaces, "NAMESPACES" },
#endif
{ config_parse_cpu_shares, "SHARES" },
- { config_parse_cpu_weight, "WEIGHT" },
+ { config_parse_cg_weight, "WEIGHT" },
{ config_parse_memory_limit, "LIMIT" },
{ config_parse_device_allow, "DEVICE" },
{ config_parse_device_policy, "POLICY" },
{ config_parse_io_limit, "LIMIT" },
- { config_parse_io_weight, "WEIGHT" },
{ config_parse_io_device_weight, "DEVICEWEIGHT" },
{ config_parse_blockio_bandwidth, "BANDWIDTH" },
{ config_parse_blockio_weight, "WEIGHT" },