diff --git a/src/core/execute.c b/src/core/execute.c index 9634ef98b1..8cb16eb49b 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2089,10 +2089,10 @@ static int setup_exec_directory( } } else { r = mkdir_label(p, context->directories[type].mode); - if (r == -EEXIST) - continue; - if (r < 0) + if (r < 0 && r != -EEXIST) goto fail; + if (r == -EEXIST && !context->dynamic_user) + continue; } /* Don't change the owner of the configuration directory, as in the common case it is not written to by diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 34c496f552..f02b13e28b 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -155,7 +155,7 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add network enumerator: %m"); - r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL); + r = bus_request_name_async_may_reload_dbus(m->bus, NULL, "org.freedesktop.network1", 0, NULL); if (r < 0) return log_error_errno(r, "Failed to request name: %m"); diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 0060a1caba..b98f862be0 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1918,7 +1918,7 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to register dnssd enumerator: %m"); - r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.resolve1", 0, NULL, NULL); + r = bus_request_name_async_may_reload_dbus(m->bus, NULL, "org.freedesktop.resolve1", 0, NULL); if (r < 0) return log_error_errno(r, "Failed to request name: %m"); diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index c80fc4fcbb..1564966e52 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1726,3 +1726,124 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri return 0; } + +struct request_name_data { + const char *name; + uint64_t flags; + void *userdata; +}; + +static int reload_dbus_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + _cleanup_free_ struct request_name_data *data = userdata; + const sd_bus_error *e; + int r; + + assert(m); + assert(data); + assert(data->name); + + e = sd_bus_message_get_error(m); + if (e) { + log_error_errno(sd_bus_error_get_errno(e), "Failed to reload DBus configuration: %s", e->message); + return 1; + } + + /* Here, use the default request name handler to avoid an infinite loop of reloading and requesting. */ + r = sd_bus_request_name_async(sd_bus_message_get_bus(m), NULL, data->name, data->flags, NULL, data->userdata); + if (r < 0) + log_error_errno(r, "Failed to request name: %m"); + + return 1; +} + +static int request_name_handler_may_reload_dbus(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + _cleanup_free_ struct request_name_data *data = userdata; + uint32_t ret; + int r; + + assert(m); + assert(userdata); + + if (sd_bus_message_is_method_error(m, NULL)) { + const sd_bus_error *e = sd_bus_message_get_error(m); + + if (!sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED)) { + log_debug_errno(sd_bus_error_get_errno(e), + "Unable to request name, failing connection: %s", + e->message); + + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; + } + + log_debug_errno(sd_bus_error_get_errno(e), + "Unable to request name, retry after reloading DBus configuration: %s", + e->message); + + /* If systemd-timesyncd.service enables DynamicUser= and dbus.service + * started before the dynamic user is realized, then the DBus policy + * about timesyncd has not been enabled yet. So, let's try to reload + * DBus configuration, and after that request name again. Note that it + * seems that no privileges are necessary to call the following method. */ + + r = sd_bus_call_method_async( + sd_bus_message_get_bus(m), + NULL, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ReloadConfig", + reload_dbus_handler, + userdata, NULL); + if (r < 0) { + log_error_errno(r, "Failed to reload DBus configuration: %m"); + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; + } + + data = NULL; /* Avoid free() */ + return 1; + } + + r = sd_bus_message_read(m, "u", &ret); + if (r < 0) + return r; + + switch (ret) { + + case BUS_NAME_ALREADY_OWNER: + log_debug("Already owner of requested service name, ignoring."); + return 1; + + case BUS_NAME_IN_QUEUE: + log_debug("In queue for requested service name."); + return 1; + + case BUS_NAME_PRIMARY_OWNER: + log_debug("Successfully acquired requested service name."); + return 1; + + case BUS_NAME_EXISTS: + log_debug("Requested service name already owned, failing connection."); + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; + } + + log_debug("Unexpected response from RequestName(), failing connection."); + bus_enter_closing(sd_bus_message_get_bus(m)); + return 1; +} + +int bus_request_name_async_may_reload_dbus(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, uint64_t flags, void *userdata) { + struct request_name_data *data; + + data = new0(struct request_name_data, 1); + if (!data) + return -ENOMEM; + + data->name = name; + data->flags = flags; + data->userdata = userdata; + + return sd_bus_request_name_async(bus, ret_slot, name, flags, request_name_handler_may_reload_dbus, data); +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index a3af8d8fbc..16aeca74dd 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -182,3 +182,5 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri static inline int bus_open_system_watch_bind(sd_bus **ret) { return bus_open_system_watch_bind_with_description(ret, NULL); } + +int bus_request_name_async_may_reload_dbus(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, uint64_t flags, void *userdata); diff --git a/src/timesync/timesyncd-bus.c b/src/timesync/timesyncd-bus.c index 6243debfeb..f2527f52e4 100644 --- a/src/timesync/timesyncd-bus.c +++ b/src/timesync/timesyncd-bus.c @@ -169,100 +169,6 @@ static const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END }; -static int reload_dbus_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { - const sd_bus_error *e; - int r; - - assert(m); - - e = sd_bus_message_get_error(m); - if (e) { - log_error_errno(sd_bus_error_get_errno(e), "Failed to reload DBus configuration: %s", e->message); - return 1; - } - - /* Here, use the default request name handler to avoid an infinite loop of reloading and requesting. */ - r = sd_bus_request_name_async(sd_bus_message_get_bus(m), NULL, "org.freedesktop.timesync1", 0, NULL, NULL); - if (r < 0) - log_error_errno(r, "Failed to request name: %m"); - - return 1; -} - -static int request_name_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { - uint32_t ret; - int r; - - assert(m); - - if (sd_bus_message_is_method_error(m, NULL)) { - const sd_bus_error *e = sd_bus_message_get_error(m); - - if (!sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED)) { - log_debug_errno(sd_bus_error_get_errno(e), - "Unable to request name, failing connection: %s", - e->message); - - bus_enter_closing(sd_bus_message_get_bus(m)); - return 1; - } - - log_debug_errno(sd_bus_error_get_errno(e), - "Unable to request name, retry after reloading DBus configuration: %s", - e->message); - - /* If systemd-timesyncd.service enables DynamicUser= and dbus.service - * started before the dynamic user is realized, then the DBus policy - * about timesyncd has not been enabled yet. So, let's try to reload - * DBus configuration, and after that request name again. Note that it - * seems that no privileges are necessary to call the following method. */ - - r = sd_bus_call_method_async( - sd_bus_message_get_bus(m), - NULL, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "ReloadConfig", - reload_dbus_handler, - NULL, NULL); - if (r < 0) { - log_error_errno(r, "Failed to reload DBus configuration: %m"); - bus_enter_closing(sd_bus_message_get_bus(m)); - } - - return 1; - } - - r = sd_bus_message_read(m, "u", &ret); - if (r < 0) - return r; - - switch (ret) { - - case BUS_NAME_ALREADY_OWNER: - log_debug("Already owner of requested service name, ignoring."); - return 1; - - case BUS_NAME_IN_QUEUE: - log_debug("In queue for requested service name."); - return 1; - - case BUS_NAME_PRIMARY_OWNER: - log_debug("Successfully acquired requested service name."); - return 1; - - case BUS_NAME_EXISTS: - log_debug("Requested service name already owned, failing connection."); - bus_enter_closing(sd_bus_message_get_bus(m)); - return 1; - } - - log_debug("Unexpected response from RequestName(), failing connection."); - bus_enter_closing(sd_bus_message_get_bus(m)); - return 1; -} - int manager_connect_bus(Manager *m) { int r; @@ -279,7 +185,7 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add manager object vtable: %m"); - r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.timesync1", 0, request_name_handler, NULL); + r = bus_request_name_async_may_reload_dbus(m->bus, NULL, "org.freedesktop.timesync1", 0, NULL); if (r < 0) return log_error_errno(r, "Failed to request name: %m"); diff --git a/sysusers.d/systemd.conf.m4 b/sysusers.d/systemd.conf.m4 index 82e23ca5a8..2315b56e3f 100644 --- a/sysusers.d/systemd.conf.m4 +++ b/sysusers.d/systemd.conf.m4 @@ -6,12 +6,6 @@ # (at your option) any later version. g systemd-journal - - -m4_ifdef(`ENABLE_NETWORKD', -u systemd-network - "systemd Network Management" -)m4_dnl -m4_ifdef(`ENABLE_RESOLVE', -u systemd-resolve - "systemd Resolver" -)m4_dnl m4_ifdef(`ENABLE_COREDUMP', u systemd-coredump - "systemd Core Dumper" )m4_dnl diff --git a/tmpfiles.d/systemd.conf.m4 b/tmpfiles.d/systemd.conf.m4 index d39c9cbbcf..222a42422d 100644 --- a/tmpfiles.d/systemd.conf.m4 +++ b/tmpfiles.d/systemd.conf.m4 @@ -17,9 +17,9 @@ d /run/systemd/users 0755 root root - d /run/systemd/machines 0755 root root - d /run/systemd/shutdown 0755 root root - m4_ifdef(`ENABLE_NETWORKD', -d /run/systemd/netif 0755 systemd-network systemd-network - -d /run/systemd/netif/links 0755 systemd-network systemd-network - -d /run/systemd/netif/leases 0755 systemd-network systemd-network - +d /run/systemd/netif 0755 root root - +d /run/systemd/netif/links 0755 root root - +d /run/systemd/netif/leases 0755 root root - )m4_dnl d /run/log 0755 root root - diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in index d05b334722..adb219a01d 100644 --- a/units/systemd-networkd.service.in +++ b/units/systemd-networkd.service.in @@ -13,7 +13,7 @@ Documentation=man:systemd-networkd.service(8) ConditionCapability=CAP_NET_ADMIN DefaultDependencies=no # systemd-udevd.service can be dropped once tuntap is moved to netlink -After=systemd-udevd.service network-pre.target systemd-sysusers.service systemd-sysctl.service +After=systemd-udevd.service network-pre.target systemd-sysctl.service Before=network.target multi-user.target shutdown.target Conflicts=shutdown.target Wants=network.target @@ -25,9 +25,9 @@ RestartSec=0 ExecStart=!!@rootlibexecdir@/systemd-networkd WatchdogSec=3min User=systemd-network +DynamicUser=yes CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW -ProtectSystem=strict ProtectHome=yes ProtectControlGroups=yes ProtectKernelModules=yes diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in index a939f7259c..7b92735f19 100644 --- a/units/systemd-resolved.service.in +++ b/units/systemd-resolved.service.in @@ -14,7 +14,7 @@ Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients DefaultDependencies=no -After=systemd-sysusers.service systemd-networkd.service +After=systemd-networkd.service Before=network.target nss-lookup.target shutdown.target Conflicts=shutdown.target Wants=nss-lookup.target @@ -26,11 +26,10 @@ RestartSec=0 ExecStart=!!@rootlibexecdir@/systemd-resolved WatchdogSec=3min User=systemd-resolve +DynamicUser=yes CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE -PrivateTmp=yes PrivateDevices=yes -ProtectSystem=strict ProtectHome=yes ProtectControlGroups=yes ProtectKernelTunables=yes diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in index 913dac773a..6bfe28627b 100644 --- a/units/systemd-timesyncd.service.in +++ b/units/systemd-timesyncd.service.in @@ -13,7 +13,7 @@ Documentation=man:systemd-timesyncd.service(8) ConditionCapability=CAP_SYS_TIME ConditionVirtualization=!container DefaultDependencies=no -After=systemd-remount-fs.service systemd-sysusers.service +After=systemd-remount-fs.service Before=time-sync.target sysinit.target shutdown.target Conflicts=shutdown.target Wants=time-sync.target