mirror of
https://github.com/systemd/systemd.git
synced 2025-09-02 17:49:53 +03:00
hostnamed: allow networkd to set the transient hostname
systemd-networkd runs as user "systemd-network" and thus is not privileged to set the transient hostname: systemd-networkd[516]: ens3: Could not set hostname: Interactive authentication required. Standard polkit *.policy files do not have a syntax for granting privileges to a user, so ship a pklocalauthority (for polkit < 106) and a JavaScript rules file (for polkit >= 106) that grants the "systemd-network" system user that privilege. Add DnsmasqClientTest.test_transient_hostname() test to networkd-test.py to cover this. Make do_test() a bit more flexible by interpreting "coldplug==None" as "test sets up the interface by itself". Change DnsmasqClientTest to set up test_eth42 with a fixed MAC address so that we can configure dnsmasq to send a special host name for that. Fixes #4646
This commit is contained in:
16
Makefile.am
16
Makefile.am
@ -55,6 +55,8 @@ pamconfdir=@pamconfdir@
|
|||||||
pkgconfigdatadir=$(datadir)/pkgconfig
|
pkgconfigdatadir=$(datadir)/pkgconfig
|
||||||
pkgconfiglibdir=$(libdir)/pkgconfig
|
pkgconfiglibdir=$(libdir)/pkgconfig
|
||||||
polkitpolicydir=$(datadir)/polkit-1/actions
|
polkitpolicydir=$(datadir)/polkit-1/actions
|
||||||
|
polkitrulesdir=$(datadir)/polkit-1/rules.d
|
||||||
|
polkitpkladir=$(localstatedir)/lib/polkit-1/localauthority/10-vendor.d
|
||||||
bashcompletiondir=@bashcompletiondir@
|
bashcompletiondir=@bashcompletiondir@
|
||||||
zshcompletiondir=@zshcompletiondir@
|
zshcompletiondir=@zshcompletiondir@
|
||||||
rpmmacrosdir=$(prefix)/lib/rpm/macros.d
|
rpmmacrosdir=$(prefix)/lib/rpm/macros.d
|
||||||
@ -116,6 +118,8 @@ pkgconfiglib_DATA =
|
|||||||
polkitpolicy_in_in_files =
|
polkitpolicy_in_in_files =
|
||||||
polkitpolicy_in_files =
|
polkitpolicy_in_files =
|
||||||
polkitpolicy_files =
|
polkitpolicy_files =
|
||||||
|
polkitrules_files =
|
||||||
|
polkitpkla_files =
|
||||||
dist_udevrules_DATA =
|
dist_udevrules_DATA =
|
||||||
nodist_udevrules_DATA =
|
nodist_udevrules_DATA =
|
||||||
dist_pkgsysconf_DATA =
|
dist_pkgsysconf_DATA =
|
||||||
@ -4836,8 +4840,16 @@ endif
|
|||||||
polkitpolicy_in_files += \
|
polkitpolicy_in_files += \
|
||||||
src/hostname/org.freedesktop.hostname1.policy.in
|
src/hostname/org.freedesktop.hostname1.policy.in
|
||||||
|
|
||||||
|
polkitrules_files += \
|
||||||
|
src/hostname/systemd-networkd-hostname.rules
|
||||||
|
|
||||||
|
polkitpkla_files += \
|
||||||
|
src/hostname/systemd-networkd-hostname.pkla
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
units/systemd-hostnamed.service.in
|
units/systemd-hostnamed.service.in \
|
||||||
|
src/hostname/systemd-networkd-hostname.rules \
|
||||||
|
src/hostname/systemd-networkd-hostname.pkla
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
dist_systemunit_DATA_busnames += \
|
dist_systemunit_DATA_busnames += \
|
||||||
@ -6189,6 +6201,8 @@ if ENABLE_POLKIT
|
|||||||
nodist_polkitpolicy_DATA = \
|
nodist_polkitpolicy_DATA = \
|
||||||
$(polkitpolicy_files) \
|
$(polkitpolicy_files) \
|
||||||
$(polkitpolicy_in_in_files:.policy.in.in=.policy)
|
$(polkitpolicy_in_in_files:.policy.in.in=.policy)
|
||||||
|
polkitrules_DATA = $(polkitrules_files)
|
||||||
|
polkitpkla_DATA = $(polkitpkla_files)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
|
4
src/hostname/systemd-networkd-hostname.pkla
Normal file
4
src/hostname/systemd-networkd-hostname.pkla
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[Allow systemd-networkd to set transient hostname]
|
||||||
|
Identity=unix-user:systemd-network
|
||||||
|
Action=org.freedesktop.hostname1.set-hostname
|
||||||
|
ResultAny=yes
|
5
src/hostname/systemd-networkd-hostname.rules
Normal file
5
src/hostname/systemd-networkd-hostname.rules
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if (action.id == "org.freedesktop.hostname1.set-hostname" && subject.user == "systemd-network") {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
@ -123,10 +123,13 @@ DHCP=%s
|
|||||||
# create interface first, then start networkd
|
# create interface first, then start networkd
|
||||||
self.create_iface(ipv6=ipv6)
|
self.create_iface(ipv6=ipv6)
|
||||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
else:
|
elif coldplug is not None:
|
||||||
# start networkd first, then create interface
|
# start networkd first, then create interface
|
||||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
self.create_iface(ipv6=ipv6)
|
self.create_iface(ipv6=ipv6)
|
||||||
|
else:
|
||||||
|
# "None" means test sets up interface by itself
|
||||||
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([self.networkd_wait_online, '--interface',
|
subprocess.check_call([self.networkd_wait_online, '--interface',
|
||||||
@ -196,7 +199,7 @@ DHCP=%s
|
|||||||
else:
|
else:
|
||||||
self.fail('nameserver 192.168.5.1 not found in ' + RESOLV_CONF)
|
self.fail('nameserver 192.168.5.1 not found in ' + RESOLV_CONF)
|
||||||
|
|
||||||
if not coldplug:
|
if coldplug is False:
|
||||||
# check post-down.d hook
|
# check post-down.d hook
|
||||||
self.shutdown_iface()
|
self.shutdown_iface()
|
||||||
|
|
||||||
@ -293,13 +296,15 @@ class DnsmasqClientTest(ClientTestBase, unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.dnsmasq = None
|
self.dnsmasq = None
|
||||||
|
self.iface_mac = 'de:ad:be:ef:47:11'
|
||||||
|
|
||||||
def create_iface(self, ipv6=False, dnsmasq_opts=None):
|
def create_iface(self, ipv6=False, dnsmasq_opts=None):
|
||||||
'''Create test interface with DHCP server behind it'''
|
'''Create test interface with DHCP server behind it'''
|
||||||
|
|
||||||
# add veth pair
|
# add veth pair
|
||||||
subprocess.check_call(['ip', 'link', 'add', 'name', self.iface, 'type',
|
subprocess.check_call(['ip', 'link', 'add', 'name', self.iface,
|
||||||
'veth', 'peer', 'name', self.if_router])
|
'address', self.iface_mac,
|
||||||
|
'type', 'veth', 'peer', 'name', self.if_router])
|
||||||
|
|
||||||
# give our router an IP
|
# give our router an IP
|
||||||
subprocess.check_call(['ip', 'a', 'flush', 'dev', self.if_router])
|
subprocess.check_call(['ip', 'a', 'flush', 'dev', self.if_router])
|
||||||
@ -415,6 +420,19 @@ Domains= ~company ~lab''')
|
|||||||
self.assertRegex(general_log, 'query.*megasearch.net')
|
self.assertRegex(general_log, 'query.*megasearch.net')
|
||||||
self.assertNotIn('megasearch.net', vpn_log)
|
self.assertNotIn('megasearch.net', vpn_log)
|
||||||
|
|
||||||
|
def test_transient_hostname(self):
|
||||||
|
'''networkd sets transient hostname from DHCP'''
|
||||||
|
|
||||||
|
self.create_iface(dnsmasq_opts=['--dhcp-host=%s,192.168.5.210,testgreen' % self.iface_mac])
|
||||||
|
self.do_test(coldplug=None, extra_opts='IPv6AcceptRA=False', dhcp_mode='ipv4')
|
||||||
|
|
||||||
|
# should have received the fixed IP above
|
||||||
|
out = subprocess.check_output(['ip', '-4', 'a', 'show', 'dev', self.iface])
|
||||||
|
self.assertRegex(out, b'inet 192.168.5.210/24 .* scope global dynamic')
|
||||||
|
|
||||||
|
# should have set transient hostname
|
||||||
|
self.assertIn(b'testgreen', subprocess.check_output(['hostnamectl']))
|
||||||
|
|
||||||
|
|
||||||
class NetworkdClientTest(ClientTestBase, unittest.TestCase):
|
class NetworkdClientTest(ClientTestBase, unittest.TestCase):
|
||||||
'''Test networkd client against networkd server'''
|
'''Test networkd client against networkd server'''
|
||||||
|
Reference in New Issue
Block a user