Compare commits

...

13 Commits

Author SHA1 Message Date
Chris Down bbfd9f513b
Merge pull request #14423 from danielshahaf/zsh-add-missing-completions
zsh: Add missing completions
2020-01-07 19:34:55 +00:00
Lennart Poettering 4353974d75 boot: fix osrel parser
let's check VERSION instead of VERSION_ID where appropriate.

Fixes: #14493
2020-01-07 19:32:14 +00:00
Anita Zhang ffe61e19cb
Merge pull request #14472 from poettering/test-43-fixes
Various robustness fixes for TEST-43-PRIVATEUSER-UNPRIV
2020-01-07 10:53:13 -08:00
Lennart Poettering 65ad4ad89d
Merge pull request #14499 from yuwata/network-gateway-dhcp
network: static route via DHCP gateway
2020-01-07 19:17:51 +01:00
Iain Lane 625077264b units: Split modprobing out into a separate service unit
Devices referred to by `DeviceAllow=` sandboxing are resolved into their
corresponding major numbers when the unit is loaded by looking at
`/proc/devices`. If a reference is made to a device which is not yet
available, the `DeviceAllow` is ignored and the unit's processes cannot
access that device.

In both logind and nspawn, we have `DeviceAllow=` lines, and `modprobe`
in `ExecStartPre=` to load some kernel modules. Those kernel modules
cause device nodes to become available when they are loaded: the device
nodes may not exist when the unit itself is loaded. This means that the
unit's processes will not be able to access the device since the
`DeviceAllow=` will have been resolved earlier and denied it.

One way to fix this would be to re-evaluate the available devices and
re-apply the policy to the cgroup, but this cannot work atomically on
cgroupsv1. So we fall back to a second approach: instead of running
`modprobe` via `ExecStartPre`, we move this out to a separate unit and
order it before the units which want the module.

Closes #14322.
Fixes: #13943.
2020-01-07 18:37:30 +01:00
Yu Watanabe 214c5bae09 test-network: add test for Gateway=DHCP 2020-01-07 19:11:19 +09:00
Yu Watanabe 1985c54ff3 network: static routes via DHCP gateway
This makes Gateway= also take "DHCP". If "DHCP" is set, then the gateway
address provided by DHCP or IPv6 RA is used.

Closes #8213.
2020-01-07 19:10:54 +09:00
Lennart Poettering f9aefc91f1 testsuite: drop "systemctl is-system-running --wait" invocation
We wait for "basic.target" being reached in the user instance anyway
before allowing the user's session to start, hence doing such a wait is
unnecessary, since that would just mean we'd wait for "default.target"
on top of "basic.target", but we shouldn#t need anything of that...

Hence, let's simplify this, reduce explicit sync points.
2020-01-06 13:41:56 +01:00
Lennart Poettering e9786a5c01 test: don't rely on "nobody" user for TEST-43
The name is not as universal as we want, still, hence let's use our own
user we create with sysusers.d/. That should yield same behaviour
everywhere (and also test sysusers a bit as side effect).
2020-01-06 13:25:33 +01:00
Lennart Poettering 6e0ed2865e test: hardcode shell to use
let's make sure we always invoke our commands through /bin/sh, since
on some distros su will use /bin/nologin (or whatever is listed in
/etc/passwd) as shell otherwise and we don#t want that.
2020-01-06 13:25:33 +01:00
Daniel Shahaf fa7ea86510 zsh: Prepare for classifying systemctl commands (#14422) 2019-12-23 17:17:31 +00:00
Daniel Shahaf 1d8385b415 zsh: Complete more systemctl commands
The completion is now synced with the manual.
2019-12-23 16:49:51 +00:00
Daniel Shahaf 51a3b72634 zsh: Group systemctl subcommands as in the manual. No functional change. 2019-12-23 16:44:28 +00:00
17 changed files with 217 additions and 50 deletions

View File

@ -1216,7 +1216,9 @@
<varlistentry>
<term><varname>Gateway=</varname></term>
<listitem>
<para>As in the <literal>[Network]</literal> section.</para>
<para>Takes the gateway address or special value <literal>dhcp</literal>. If
<literal>dhcp</literal>, then the gateway address provided by DHCP (or in the IPv6 case,
provided by IPv6 RA) is used.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -3,8 +3,8 @@
(( $+functions[_systemctl_commands] )) || _systemctl_commands()
{
local -a _systemctl_cmds
_systemctl_cmds=(
local -a unit_commands=(
# Unit Commands
"list-sockets:List sockets"
"list-timers:List timers"
"list-units:List units"
@ -16,9 +16,6 @@
"try-restart:Restart one or more units if active"
"reload-or-restart:Reload one or more units if possible, otherwise start or restart"
"force-reload:Reload one or more units if possible, otherwise restart if active"
"hibernate:Hibernate the system"
"hybrid-sleep:Hibernate and suspend the system"
"suspend-then-hibernate:Suspend the system for a period of time, and then hibernate it"
"try-reload-or-restart:Reload one or more units if possible, otherwise restart if active"
"isolate:Start one unit and stop all others"
"kill:Send signal to processes of a unit"
@ -27,32 +24,64 @@
"status:Show runtime status of one or more units"
"show:Show properties of one or more units/jobs or the manager"
"cat:Show the source unit files and drop-ins"
"set-property:Sets one or more properties of a unit"
"help:Show documentation for specified units"
"reset-failed:Reset failed state for all, one, or more units"
"list-dependencies:Show unit dependency tree"
"clean:Remove configuration, state, cache, logs or runtime data of units"
)
local -a machine_commands=(
# Machine Commands
"list-machines:List the host and all running local containers"
)
local -a unit_file_commands=(
# Unit File Commands
"list-unit-files:List installed unit files"
"enable:Enable one or more unit files"
"disable:Disable one or more unit files"
"add-wants:Add Wants= dependencies to a unit"
"add-requires:Add Requires= dependencies to a unit"
"reenable:Reenable one or more unit files"
"preset:Enable/disable one or more unit files based on preset configuration"
"preset-all:Enable/disable all unit files based on preset configuration"
"set-default:Set the default target"
"get-default:Query the default target"
"edit:Edit one or more unit files"
"is-system-running:Query overall status of the system"
"help:Show documentation for specified units"
"list-dependencies:Show unit dependency tree"
"is-enabled:Check whether unit files are enabled"
"mask:Mask one or more units"
"unmask:Unmask one or more units"
"link:Link one or more units files into the search path"
"is-enabled:Check whether unit files are enabled"
"revert:Revert unit files to their vendor versions"
"add-wants:Add Wants= dependencies to a unit"
"add-requires:Add Requires= dependencies to a unit"
"set-default:Set the default target"
"get-default:Query the default target"
"edit:Edit one or more unit files"
)
local -a job_commands=(
# Job Commands
"list-jobs:List jobs"
"cancel:Cancel all, one, or more jobs"
)
local -a environment_commands=(
# Environment Commands
"show-environment:Dump environment"
"set-environment:Set one or more environment variables"
"unset-environment:Unset one or more environment variables"
"import-environment:Import environment variables set on the client"
)
local -a manager_state_commands=(
# Manager State Commands
"daemon-reload:Reload systemd manager configuration"
"daemon-reexec:Reexecute systemd manager"
"log-level:Get or set the log level"
"log-target:Get or set the log target"
"service-watchdogs:Get or set the state of software watchdogs"
)
local -a system_commands=(
# System Commands
"is-system-running:Query overall status of the system"
"default:Enter system default mode"
"rescue:Enter system rescue mode"
"emergency:Enter system emergency mode"
@ -63,8 +92,19 @@
"kexec:Shut down and reboot the system with kexec"
"exit:Ask for user instance termination"
"switch-root:Change root directory"
"revert:Revert unit files to their vendor versions"
"set-property:Sets one or more properties of a unit"
"hibernate:Hibernate the system"
"hybrid-sleep:Hibernate and suspend the system"
"suspend-then-hibernate:Suspend the system for a period of time, and then hibernate it"
)
local -a _systemctl_cmds=(
"${unit_commands[@]}"
"${machine_commands[@]}"
"${unit_file_commands[@]}"
"${job_commands[@]}"
"${environment_commands[@]}"
"${manager_state_commands[@]}"
"${system_commands[@]}"
)
if (( CURRENT == 1 )); then

View File

@ -1958,7 +1958,7 @@ static VOID config_entry_add_linux(
continue;
}
if (strcmpa((CHAR8 *)"VERSION_ID", key) == 0) {
if (strcmpa((CHAR8 *)"VERSION", key) == 0) {
FreePool(os_version);
os_version = stra_to_str(value);
continue;

View File

@ -377,6 +377,23 @@ static int link_set_dhcp_routes(Link *link) {
return log_link_error_errno(link, r, "Could not set router: %m");
}
Route *rt;
LIST_FOREACH(routes, rt, link->network->static_routes) {
if (!rt->gateway_from_dhcp)
continue;
if (rt->family != AF_INET)
continue;
rt->gw.in = router[0];
r = route_configure(rt, link, dhcp4_route_handler);
if (r < 0)
return log_link_error_errno(link, r, "Could not set gateway: %m");
if (r > 0)
link->dhcp4_messages++;
}
return link_set_dns_routes(link, &address);
}
@ -480,6 +497,20 @@ static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_
if (remove_all || !set_contains(link->dhcp_routes, route))
(void) route_remove(route, link, NULL);
Route *rt;
LIST_FOREACH(routes, rt, link->network->static_routes) {
if (!rt->gateway_from_dhcp)
continue;
if (rt->family != AF_INET)
continue;
if (!remove_all && in4_addr_equal(router, &rt->gw.in))
continue;
(void) route_remove(rt, link, NULL);
}
return 0;
}

View File

@ -1039,6 +1039,8 @@ int link_request_set_routes(Link *link) {
/* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
for (phase = 0; phase < _PHASE_MAX; phase++)
LIST_FOREACH(routes, rt, link->network->static_routes) {
if (rt->gateway_from_dhcp)
continue;
if ((in_addr_is_null(rt->family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY))
continue;

View File

@ -169,6 +169,26 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (r > 0)
link->ndisc_messages++;
Route *route_gw;
LIST_FOREACH(routes, route_gw, link->network->static_routes) {
if (!route_gw->gateway_from_dhcp)
continue;
if (route_gw->family != AF_INET6)
continue;
route_gw->gw = gateway;
r = route_configure(route_gw, link, ndisc_netlink_route_message_handler);
if (r < 0) {
log_link_error_errno(link, r, "Could not set gateway: %m");
link_enter_failed(link);
return r;
}
if (r > 0)
link->ndisc_messages++;
}
return 0;
}

View File

@ -998,11 +998,20 @@ int config_parse_gateway(
/* we are not in an Route section, so treat
* this as the special '0' section */
r = route_new_static(network, NULL, 0, &n);
} else
if (r < 0)
return r;
} else {
r = route_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
if (streq(rvalue, "dhcp")) {
n->gateway_from_dhcp = true;
TAKE_PTR(n);
return 0;
}
}
if (n->family == AF_UNSPEC)
r = in_addr_from_string_auto(rvalue, &n->family, &n->gw);
else

View File

@ -48,6 +48,7 @@ struct Route {
unsigned char pref;
unsigned flags;
int gateway_onlink;
bool gateway_from_dhcp;
union in_addr_union gw;
union in_addr_union dst;

View File

@ -15,20 +15,23 @@ test_setup() {
mask_supporting_services
usermod --root $initdir -d /home/nobody -s /bin/bash nobody
mkdir $initdir/home $initdir/home/nobody
# Ubuntu's equivalent is nogroup
chown nobody:nobody $initdir/home/nobody || chown nobody:nogroup $initdir/home/nobody
# Allocate user for running test case under
mkdir -p $initdir/etc/sysusers.d
cat >$initdir/etc/sysusers.d/testuser.conf <<EOF
u testuser 4711 "Test User" /home/testuser
EOF
enable_user_manager nobody
mkdir -p $initdir/home/testuser -m 0700
chown 4711:4711 $initdir/home/testuser
nobody_uid=$(id -u nobody)
enable_user_manager testuser
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
After=systemd-logind.service user@$nobody_uid.service
After=systemd-logind.service user@4711.service
Wants=user@4711.service
[Service]
ExecStart=/testsuite.sh

View File

@ -7,15 +7,13 @@ systemd-analyze log-level debug
runas() {
declare userid=$1
shift
su "$userid" -c 'XDG_RUNTIME_DIR=/run/user/$UID "$@"' -- sh "$@"
su "$userid" -s /bin/sh -c 'XDG_RUNTIME_DIR=/run/user/$UID exec "$@"' -- sh "$@"
}
runas nobody systemctl --user --wait is-system-running
runas nobody systemd-run --user --unit=test-private-users \
runas testuser systemd-run --user --unit=test-private-users \
-p PrivateUsers=yes -P echo hello
runas nobody systemd-run --user --unit=test-private-tmp-innerfile \
runas testuser systemd-run --user --unit=test-private-tmp-innerfile \
-p PrivateUsers=yes -p PrivateTmp=yes \
-P touch /tmp/innerfile.txt
# File should not exist outside the job's tmp directory.
@ -23,31 +21,31 @@ test ! -e /tmp/innerfile.txt
touch /tmp/outerfile.txt
# File should not appear in unit's private tmp.
runas nobody systemd-run --user --unit=test-private-tmp-outerfile \
runas testuser systemd-run --user --unit=test-private-tmp-outerfile \
-p PrivateUsers=yes -p PrivateTmp=yes \
-P test ! -e /tmp/outerfile.txt
# Confirm that creating a file in home works
runas nobody systemd-run --user --unit=test-unprotected-home \
-P touch /home/nobody/works.txt
test -e /home/nobody/works.txt
runas testuser systemd-run --user --unit=test-unprotected-home \
-P touch /home/testuser/works.txt
test -e /home/testuser/works.txt
# Confirm that creating a file in home is blocked under read-only
runas nobody systemd-run --user --unit=test-protect-home-read-only \
runas testuser systemd-run --user --unit=test-protect-home-read-only \
-p PrivateUsers=yes -p ProtectHome=read-only \
-P bash -c '
test -e /home/nobody/works.txt
! touch /home/nobody/blocked.txt
test -e /home/testuser/works.txt
! touch /home/testuser/blocked.txt
'
test ! -e /home/nobody/blocked.txt
test ! -e /home/testuser/blocked.txt
# Check that tmpfs hides the whole directory
runas nobody systemd-run --user --unit=test-protect-home-tmpfs \
runas testuser systemd-run --user --unit=test-protect-home-tmpfs \
-p PrivateUsers=yes -p ProtectHome=tmpfs \
-P test ! -e /home/nobody
-P test ! -e /home/testuser
# Confirm that home, /root, and /run/user are inaccessible under "yes"
runas nobody systemd-run --user --unit=test-protect-home-yes \
runas testuser systemd-run --user --unit=test-protect-home-yes \
-p PrivateUsers=yes -p ProtectHome=yes \
-P bash -c '
test "$(stat -c %a /home)" = "0"
@ -59,7 +57,7 @@ runas nobody systemd-run --user --unit=test-protect-home-yes \
# namespace (no CAP_SETGID in the parent namespace to write the additional
# mapping of the user supplied group and thus cannot change groups to an
# unmapped group ID)
! runas nobody systemd-run --user --unit=test-group-fail \
! runas testuser systemd-run --user --unit=test-group-fail \
-p PrivateUsers=yes -p Group=daemon \
-P true

View File

@ -0,0 +1,10 @@
[Match]
Name=veth99
[Network]
DHCP=ipv4
IPv6AcceptRA=no
[Route]
Gateway=dhcp
Destination=10.0.0.0/8

View File

@ -0,0 +1,9 @@
[Match]
Name=veth99
[Network]
DHCP=ipv6
[Route]
Gateway=dhcp
Destination=2001:1234:5:9fff:ff:ff:ff:ff/128

View File

@ -2659,6 +2659,8 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
'25-vrf.network',
'dhcp-client-anonymize.network',
'dhcp-client-decline.network',
'dhcp-client-gateway-ipv4.network',
'dhcp-client-gateway-ipv6.network',
'dhcp-client-gateway-onlink-implicit.network',
'dhcp-client-ipv4-dhcp-settings.network',
'dhcp-client-ipv4-only-ipv6-disabled.network',
@ -3145,6 +3147,30 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output)
self.assertEqual(output, '')
def test_dhcp_client_gateway_ipv4(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
'dhcp-client-gateway-ipv4.network')
start_networkd()
self.wait_online(['veth-peer:carrier'])
start_dnsmasq()
self.wait_online(['veth99:routable', 'veth-peer:routable'])
output = check_output('ip route list dev veth99 10.0.0.0/8')
print(output)
self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto static')
def test_dhcp_client_gateway_ipv6(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
'dhcp-client-gateway-ipv6.network')
start_networkd()
self.wait_online(['veth-peer:carrier'])
start_dnsmasq()
self.wait_online(['veth99:routable', 'veth-peer:routable'])
output = check_output('ip -6 route list dev veth99 2001:1234:5:9fff:ff:ff:ff:ff')
print(output)
self.assertRegex(output, 'via fe80::1034:56ff:fe78:9abd')
def test_dhcp_client_gateway_onlink_implicit(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
'dhcp-client-gateway-onlink-implicit.network')

View File

@ -35,6 +35,7 @@ units = [
['local-fs.target', ''],
['machine.slice', 'ENABLE_MACHINED'],
['machines.target', 'ENABLE_MACHINED'],
['modprobe@.service', ''],
['multi-user.target', '',
'runlevel2.target runlevel3.target runlevel4.target'],
['network-online.target', ''],

16
units/modprobe@.service Normal file
View File

@ -0,0 +1,16 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Load kernel module %i
Documentation=man:modprobe(8)
[Service]
Type=oneshot
ExecStart=-/sbin/modprobe -abq %I

View File

@ -12,8 +12,8 @@ Description=Login Service
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
Wants=user.slice
After=nss-user-lookup.target user.slice
Wants=user.slice modprobe@drm.service
After=nss-user-lookup.target user.slice modprobe@drm.service
# Ask for the dbus socket.
Wants=dbus.socket
@ -29,7 +29,6 @@ DeviceAllow=char-input rw
DeviceAllow=char-tty rw
DeviceAllow=char-vcs rw
# Make sure the DeviceAllow= lines above can work correctly when referenceing char-drm
ExecStartPre=-/sbin/modprobe -abq drm
ExecStart=@rootlibexecdir@/systemd-logind
FileDescriptorStoreMax=512
IPAddressDeny=any

View File

@ -10,14 +10,14 @@
[Unit]
Description=Container %i
Documentation=man:systemd-nspawn(1)
Wants=modprobe@tun.service modprobe@loop.service modprobe@dm-mod.service
PartOf=machines.target
Before=machines.target
After=network.target systemd-resolved.service
After=network.target systemd-resolved.service modprobe@tun.service modprobe@loop.service modprobe@dm-mod.service
RequiresMountsFor=/var/lib/machines
[Service]
# Make sure the DeviceAllow= lines below can properly resolve the 'block-loop' expression (and others)
ExecStartPre=-/sbin/modprobe -abq tun loop dm-mod
ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth -U --settings=override --machine=%i
KillMode=mixed
Type=notify