mirror of
https://github.com/systemd/systemd.git
synced 2025-01-03 05:18:09 +03:00
parent
0d298a771a
commit
e76fcd0e40
@ -3359,7 +3359,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b ProtectHostname = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s ProtectHostnameEx = '...';
|
||||
readonly (ss) ProtectHostnameEx = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b MemoryKSM = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -4885,8 +4885,9 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
<para><varname>ProtectHostnameEx</varname> implement the destination parameter of the
|
||||
unit file setting <varname>ProtectHostname=</varname> listed in
|
||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
Unlike boolean <varname>ProtectHostname</varname>, <varname>ProtectHostnameEx</varname>
|
||||
is a string type.</para>
|
||||
Unlike boolean <varname>ProtectHostname</varname>, <varname>ProtectHostnameEx</varname> is a pair of
|
||||
strings, the first one is a boolean string or special value <literal>private</literal>, and the second
|
||||
one is an optional private hostname that will be set in a new UTS namespace for the unit.</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
@ -5552,7 +5553,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b ProtectHostname = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s ProtectHostnameEx = '...';
|
||||
readonly (ss) ProtectHostnameEx = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b MemoryKSM = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -7561,7 +7562,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b ProtectHostname = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s ProtectHostnameEx = '...';
|
||||
readonly (ss) ProtectHostnameEx = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b MemoryKSM = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -9537,7 +9538,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b ProtectHostname = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s ProtectHostnameEx = '...';
|
||||
readonly (ss) ProtectHostnameEx = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b MemoryKSM = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
|
@ -2062,11 +2062,13 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
||||
<varlistentry>
|
||||
<term><varname>ProtectHostname=</varname></term>
|
||||
|
||||
<listitem><para>Takes a boolean argument or <literal>private</literal>. If enabled, sets up a new UTS namespace
|
||||
for the executed processes. If set to a true value, changing hostname or domainname via
|
||||
<function>sethostname()</function> and <function>setdomainname()</function> system calls is prevented. If set to
|
||||
<literal>private</literal>, changing hostname or domainname is allowed but only affects the unit's UTS namespace.
|
||||
Defaults to off.</para>
|
||||
<listitem><para>Takes a boolean argument or <literal>private</literal>. If enabled, sets up a new UTS
|
||||
namespace for the executed processes. If enabled, a hostname can be optionally specified following a
|
||||
colon (e.g. <literal>yes:foo</literal> or <literal>private:host.example.com</literal>), and the
|
||||
hostname is set in the new UTS namespace for the unit. If set to a true value, changing hostname or
|
||||
domainname via <function>sethostname()</function> and <function>setdomainname()</function> system
|
||||
calls is prevented. If set to <literal>private</literal>, changing hostname or domainname is allowed
|
||||
but only affects the unit's UTS namespace. Defaults to off.</para>
|
||||
|
||||
<para>Note that the implementation of this setting might be impossible (for example if UTS namespaces
|
||||
are not available), and the unit should be written in a way that does not solely rely on this setting
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "creds-util.h"
|
||||
#include "dbus-execute.h"
|
||||
#include "dbus-util.h"
|
||||
#include "dns-domain.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-list.h"
|
||||
#include "escape.h"
|
||||
@ -21,6 +22,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "ioprio-util.h"
|
||||
#include "journal-file.h"
|
||||
@ -64,7 +66,6 @@ static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_tmp_ex, "s", PrivateTmp,
|
||||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_users_ex, "s", PrivateUsers, private_users_to_string);
|
||||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_protect_control_groups_ex, "s", ProtectControlGroups, protect_control_groups_to_string);
|
||||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_pids, "s", PrivatePIDs, private_pids_to_string);
|
||||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_protect_hostname_ex, "s", ProtectHostname, protect_hostname_to_string);
|
||||
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 BUS_DEFINE_PROPERTY_GET(property_get_cpu_affinity_from_numa, "b", ExecContext, exec_context_get_cpu_affinity_from_numa);
|
||||
@ -1084,6 +1085,20 @@ static int property_get_protect_hostname(
|
||||
return sd_bus_message_append_basic(reply, 'b', &b);
|
||||
}
|
||||
|
||||
static int property_get_protect_hostname_ex(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExecContext *c = ASSERT_PTR(userdata);
|
||||
|
||||
return sd_bus_message_append(reply, "(ss)", protect_hostname_to_string(c->protect_hostname), c->private_hostname);
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@ -1259,7 +1274,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ProtectHostname", "b", property_get_protect_hostname, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ProtectHostnameEx", "s", property_get_protect_hostname_ex, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ProtectHostnameEx", "(ss)", property_get_protect_hostname_ex, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("MemoryKSM", "b", bus_property_get_tristate, offsetof(ExecContext, memory_ksm), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NetworkNamespacePath", "s", NULL, offsetof(ExecContext, network_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IPCNamespacePath", "s", NULL, offsetof(ExecContext, ipc_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@ -2027,21 +2042,29 @@ int bus_exec_context_set_transient_property(
|
||||
}
|
||||
|
||||
if (streq(name, "ProtectHostnameEx")) {
|
||||
const char *s;
|
||||
ProtectHostname t;
|
||||
const char *s, *h = NULL;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
r = sd_bus_message_read(message, "(ss)", &s, &h);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
t = protect_hostname_from_string(s);
|
||||
if (t < 0)
|
||||
if (!isempty(h) && !hostname_is_valid(h, /* flags = */ 0))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname in %s setting: %s", name, h);
|
||||
|
||||
ProtectHostname t = protect_hostname_from_string(s);
|
||||
if (t < 0 || (t == PROTECT_HOSTNAME_NO && !isempty(h)))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->protect_hostname = t;
|
||||
(void) unit_write_settingf(u, flags, name, "ProtectHostname=%s",
|
||||
protect_hostname_to_string(c->protect_hostname));
|
||||
r = free_and_strdup(&c->private_hostname, empty_to_null(h));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) unit_write_settingf(u, flags, name, "ProtectHostname=%s%s%s",
|
||||
protect_hostname_to_string(c->protect_hostname),
|
||||
c->private_hostname ? ":" : "",
|
||||
strempty(c->private_hostname));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "exit-status.h"
|
||||
#include "fd-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-setup.h"
|
||||
#include "io-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "journal-send.h"
|
||||
@ -1698,6 +1699,8 @@ static int apply_restrict_filesystems(const ExecContext *c, const ExecParameters
|
||||
#endif
|
||||
|
||||
static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p, int *ret_exit_status) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(p);
|
||||
|
||||
@ -1714,6 +1717,13 @@ static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p,
|
||||
log_exec_warning(c, p,
|
||||
"ProtectHostname=%s is configured, but UTS namespace setup is prohibited (container manager?), ignoring namespace setup.",
|
||||
protect_hostname_to_string(c->protect_hostname));
|
||||
|
||||
} else if (c->private_hostname) {
|
||||
r = sethostname_idempotent(c->private_hostname);
|
||||
if (r < 0) {
|
||||
*ret_exit_status = EXIT_NAMESPACE;
|
||||
return log_exec_error_errno(c, p, r, "Failed to set private hostname '%s': %m", c->private_hostname);
|
||||
}
|
||||
}
|
||||
} else
|
||||
log_exec_warning(c, p,
|
||||
@ -1722,8 +1732,6 @@ static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p,
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
if (c->protect_hostname == PROTECT_HOSTNAME_YES) {
|
||||
int r;
|
||||
|
||||
if (skip_seccomp_unavailable(c, p, "ProtectHostname="))
|
||||
return 0;
|
||||
|
||||
|
@ -1982,6 +1982,10 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2884,6 +2888,10 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
|
||||
c->protect_hostname = protect_hostname_from_string(val);
|
||||
if (c->protect_hostname < 0)
|
||||
return -EINVAL;
|
||||
} else if ((val = startswith(l, "exec-context-private-hostname="))) {
|
||||
r = free_and_strdup(&c->private_hostname, val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-context-protect-proc="))) {
|
||||
c->protect_proc = protect_proc_from_string(val);
|
||||
if (c->protect_proc < 0)
|
||||
|
@ -723,6 +723,8 @@ void exec_context_done(ExecContext *c) {
|
||||
c->root_image_policy = image_policy_free(c->root_image_policy);
|
||||
c->mount_image_policy = image_policy_free(c->mount_image_policy);
|
||||
c->extension_image_policy = image_policy_free(c->extension_image_policy);
|
||||
|
||||
c->private_hostname = mfree(c->private_hostname);
|
||||
}
|
||||
|
||||
int exec_context_destroy_runtime_directory(const ExecContext *c, const char *runtime_prefix) {
|
||||
@ -1066,7 +1068,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||
"%sRestrictRealtime: %s\n"
|
||||
"%sRestrictSUIDSGID: %s\n"
|
||||
"%sKeyringMode: %s\n"
|
||||
"%sProtectHostname: %s\n"
|
||||
"%sProtectHostname: %s%s%s\n"
|
||||
"%sProtectProc: %s\n"
|
||||
"%sProcSubset: %s\n",
|
||||
prefix, c->umask,
|
||||
@ -1093,7 +1095,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||
prefix, yes_no(c->restrict_realtime),
|
||||
prefix, yes_no(c->restrict_suid_sgid),
|
||||
prefix, exec_keyring_mode_to_string(c->keyring_mode),
|
||||
prefix, protect_hostname_to_string(c->protect_hostname),
|
||||
prefix, protect_hostname_to_string(c->protect_hostname), c->private_hostname ? ":" : "", strempty(c->private_hostname),
|
||||
prefix, protect_proc_to_string(c->protect_proc),
|
||||
prefix, proc_subset_to_string(c->proc_subset));
|
||||
|
||||
|
@ -337,6 +337,7 @@ struct ExecContext {
|
||||
ProtectHome protect_home;
|
||||
PrivatePIDs private_pids;
|
||||
ProtectHostname protect_hostname;
|
||||
char *private_hostname;
|
||||
|
||||
bool dynamic_user;
|
||||
bool remove_ipc;
|
||||
|
@ -180,7 +180,7 @@
|
||||
{% else %}
|
||||
{{type}}.SmackProcessLabel, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
|
||||
{% endif %}
|
||||
{{type}}.ProtectHostname, config_parse_protect_hostname, 0, offsetof({{type}}, exec_context.protect_hostname)
|
||||
{{type}}.ProtectHostname, config_parse_protect_hostname, 0, offsetof({{type}}, exec_context)
|
||||
{{type}}.MemoryKSM, config_parse_tristate, 0, offsetof({{type}}, exec_context.memory_ksm)
|
||||
{%- endmacro -%}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "fs-util.h"
|
||||
#include "fstab-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "ioprio-util.h"
|
||||
#include "ip-protocol-list.h"
|
||||
@ -141,7 +142,6 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMo
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_home, protect_home, ProtectHome);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_hostname, protect_hostname, ProtectHostname);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_system, protect_system, ProtectSystem);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType);
|
||||
@ -6743,3 +6743,53 @@ int config_parse_cgroup_nft_set(
|
||||
|
||||
return config_parse_nft_set(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &c->nft_set_context, u);
|
||||
}
|
||||
|
||||
int config_parse_protect_hostname(
|
||||
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 = ASSERT_PTR(data);
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
_cleanup_free_ char *h = NULL, *p = NULL;
|
||||
int r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
c->protect_hostname = PROTECT_HOSTNAME_NO;
|
||||
c->private_hostname = mfree(c->private_hostname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *colon = strchr(rvalue, ':');
|
||||
if (colon) {
|
||||
r = unit_full_printf_full(u, colon + 1, HOST_NAME_MAX, &h);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", colon + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hostname_is_valid(h, /* flags = */ 0))
|
||||
return log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid hostname is specified to %s=, ignoring: %s", lvalue, h);
|
||||
|
||||
p = strndup(rvalue, colon - rvalue);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
ProtectHostname t = protect_hostname_from_string(p ?: rvalue);
|
||||
if (t < 0 || (t == PROTECT_HOSTNAME_NO && h))
|
||||
return log_syntax_parse_error(unit, filename, line, 0, lvalue, rvalue);
|
||||
|
||||
c->protect_hostname = t;
|
||||
free_and_replace(c->private_hostname, h);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1045,7 +1045,6 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||
"SyslogIdentifier",
|
||||
"ProtectSystem",
|
||||
"ProtectHome",
|
||||
"ProtectHostnameEx",
|
||||
"PrivateTmpEx",
|
||||
"PrivateUsersEx",
|
||||
"ProtectControlGroupsEx",
|
||||
@ -2269,6 +2268,24 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (streq(field, "ProtectHostnameEx")) {
|
||||
const char *colon = strchr(eq, ':');
|
||||
if (colon) {
|
||||
if (isempty(colon + 1))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse argument: %s=%s", field, eq);
|
||||
|
||||
_cleanup_free_ char *p = strndup(eq, colon - eq);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = sd_bus_message_append(m, "(sv)", field, "(ss)", p, colon + 1);
|
||||
} else
|
||||
r = sd_bus_message_append(m, "(sv)", field, "(ss)", eq, NULL);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,33 @@ testcase_yes() {
|
||||
# can only set hostname.
|
||||
(! systemd-run --wait -p ProtectHostname=yes hostname foo)
|
||||
|
||||
# ProtectHostname=yes can optionally take a hostname.
|
||||
systemd-run --wait -p ProtectHostnameEx=yes:hoge \
|
||||
-P bash -xec '
|
||||
test "$(hostname)" = "hoge"
|
||||
(! hostname foo)
|
||||
test "$(hostname)" = "hoge"
|
||||
'
|
||||
|
||||
# Verify host hostname is unchanged.
|
||||
test "$(hostname)" = "$LEGACY_HOSTNAME"
|
||||
test "$(hostnamectl hostname)" = "$HOSTNAME_FROM_SYSTEMD"
|
||||
|
||||
# ProtectHostname= supportes specifiers.
|
||||
mkdir -p /run/systemd/system/
|
||||
cat >/run/systemd/system/test-protect-hostname-yes@.service <<EOF
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=bash -xec 'test "\$\$(hostname)" = "%i"; (! hostname foo); test "\$\$(hostname)" = "%i"'
|
||||
ProtectHostname=yes:%i
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl start --wait test-protect-hostname-yes@hoge.example.com.service
|
||||
|
||||
# Verify host hostname is unchanged.
|
||||
test "$(hostname)" = "$LEGACY_HOSTNAME"
|
||||
test "$(hostnamectl hostname)" = "$HOSTNAME_FROM_SYSTEMD"
|
||||
|
||||
systemd-run --wait -p ProtectHostname=yes -p PrivateMounts=yes \
|
||||
findmnt --mountpoint /proc/sys/kernel/hostname
|
||||
}
|
||||
@ -36,9 +63,51 @@ testcase_private() {
|
||||
test "$(hostname)" = "$LEGACY_HOSTNAME"
|
||||
test "$(hostnamectl hostname)" = "$HOSTNAME_FROM_SYSTEMD"
|
||||
|
||||
# ProtectHostname=private can optionally take a hostname.
|
||||
systemd-run --wait -p ProtectHostnameEx=private:hoge \
|
||||
-P bash -xec '
|
||||
test "$(hostname)" = "hoge"
|
||||
hostname foo
|
||||
test "$(hostname)" = "foo"
|
||||
'
|
||||
|
||||
# Verify host hostname is unchanged.
|
||||
test "$(hostname)" = "$LEGACY_HOSTNAME"
|
||||
test "$(hostnamectl hostname)" = "$HOSTNAME_FROM_SYSTEMD"
|
||||
|
||||
# ProtectHostname= supportes specifiers.
|
||||
mkdir -p /run/systemd/system/
|
||||
cat >/run/systemd/system/test-protect-hostname-private@.service <<EOF
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=bash -xec 'test "\$\$(hostname)" = "%i"; hostname foo; test "\$\$(hostname)" = "foo"'
|
||||
ProtectHostname=private:%i
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl start --wait test-protect-hostname-private@hoge.example.com.service
|
||||
|
||||
# Verify host hostname is unchanged.
|
||||
test "$(hostname)" = "$LEGACY_HOSTNAME"
|
||||
test "$(hostnamectl hostname)" = "$HOSTNAME_FROM_SYSTEMD"
|
||||
|
||||
# Verify /proc/sys/kernel/hostname is not bind mounted from host read-only.
|
||||
(! systemd-run --wait -p ProtectHostnameEx=private -p PrivateMounts=yes \
|
||||
findmnt --mountpoint /proc/sys/kernel/hostname)
|
||||
}
|
||||
|
||||
testcase_invalid() {
|
||||
# ProtectHostname=no cannot take hostname.
|
||||
(! systemd-run --wait -p ProtectHostnameEx=no:hoge true)
|
||||
|
||||
# Invalid hostname.
|
||||
(! systemd-run --wait -p ProtectHostnameEx=yes: true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=yes:.foo true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=yes:foo.-example.com true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=yes:foo..example.com true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=private: true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=private:.foo true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=private:foo.-example.com true)
|
||||
(! systemd-run --wait -p ProtectHostnameEx=private:foo..example.com true)
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
Loading…
Reference in New Issue
Block a user