Compare commits

...

6 Commits

Author SHA1 Message Date
Pass Automated Testing Suite e3820eeaf1 path-lookup: Correct order of XDG_CONFIG_HOME and XDG_CONFIG_DIRS
According to the XDG Base Directory Specification [1] XDG_CONFIG_HOME
should take precedence over XDG_CONFIG_DIRS.

Fixes: https://github.com/systemd/systemd/issues/16095

[1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
2020-09-29 21:47:01 +02:00
nl6720 f856778b9c docs: update old documentation links 2020-09-29 21:45:06 +02:00
Yu Watanabe 88da55e28b udevadm: do not ignroe error caused by unpriviledged user invoking the command
This effectively reverts commit 67acde4869.

After commits 569ad251ad and
67acde4869, -EACCES errors are ignored,
and thus 'udevadm trigger' succeeds even when it is invoked by non-root
users. Moreover, on -EACCES error, log messages are shown in debug
level, so usually we see no message, and users are easily confused
why uevents for devices are not triggered.
2020-09-29 21:44:10 +02:00
Lennart Poettering a182fa895b
Merge pull request #17194 from poettering/dot-suffix
resolved: turn off search domain logic for queries for dot-suffixed domains
2020-09-29 15:50:06 +02:00
Lennart Poettering 3354f5003c resolved: imply SD_RESOLVED_NO_SEARCH when looking up trailing dot domains
Let's turn off the search domain logic if a trailing dot is specified
when looking up hostnames and RRs via the Varlink + D-Bus APIs (and thus
also when doing so via nss-resolve). (This doesn't affect lookups via
the stub, since for the any search path logic is done client side
anyway)

It might make sense to force the DNS protocol in this case too (and
disable LLMR + mDNS), but we'll leave that for a different PR — if it
even makes sense. It might also make sense to disable the logic of never
routing single-label lookups to the Internet if a trailing to is
specified, but this needs more discussion too.
2020-09-29 12:12:03 +02:00
Lennart Poettering 64c82c25ab dns-domain: add helper that checks whether domain is dot suffixed 2020-09-29 12:09:16 +02:00
15 changed files with 117 additions and 48 deletions

View File

@ -82,7 +82,7 @@ And now, here's the list of (hopefully) all APIs that we have introduced with sy
| [hostnamed](https://www.freedesktop.org/wiki/Software/systemd/hostnamed) | D-Bus | yes | yes | GNOME | yes | [Ubuntu](https://launchpad.net/ubuntu/+source/ubuntu-system-service), [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially | | [hostnamed](https://www.freedesktop.org/wiki/Software/systemd/hostnamed) | D-Bus | yes | yes | GNOME | yes | [Ubuntu](https://launchpad.net/ubuntu/+source/ubuntu-system-service), [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially |
| [localed](https://www.freedesktop.org/wiki/Software/systemd/localed) | D-Bus | yes | yes | GNOME | yes | [Ubuntu](https://launchpad.net/ubuntu/+source/ubuntu-system-service), [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially | | [localed](https://www.freedesktop.org/wiki/Software/systemd/localed) | D-Bus | yes | yes | GNOME | yes | [Ubuntu](https://launchpad.net/ubuntu/+source/ubuntu-system-service), [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially |
| [timedated](https://www.freedesktop.org/wiki/Software/systemd/timedated) | D-Bus | yes | yes | GNOME | yes | [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially | | [timedated](https://www.freedesktop.org/wiki/Software/systemd/timedated) | D-Bus | yes | yes | GNOME | yes | [Gentoo](http://www.gentoo.org/proj/en/desktop/gnome/openrc-settingsd.xml), [BSD](http://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary) | partially |
| [initrd interface](https://www.freedesktop.org/wiki/Software/systemd/InitrdInterface) | Environment, flag files | yes | yes | dracut, ArchLinux | yes | ArchLinux | no | | [initrd interface](https://systemd.io/INITRD_INTERFACE/) | Environment, flag files | yes | yes | dracut, ArchLinux | yes | ArchLinux | no |
| [Container interface](https://systemd.io/CONTAINER_INTERFACE) | Environment, Mounts | yes | yes | libvirt/LXC | yes | - | no | | [Container interface](https://systemd.io/CONTAINER_INTERFACE) | Environment, Mounts | yes | yes | libvirt/LXC | yes | - | no |
| [Boot Loader interface](https://systemd.io/BOOT_LOADER_INTERFACE) | EFI variables | yes | yes | gummiboot | yes | - | no | | [Boot Loader interface](https://systemd.io/BOOT_LOADER_INTERFACE) | EFI variables | yes | yes | gummiboot | yes | - | no |
| [Service bus API](https://www.freedesktop.org/wiki/Software/systemd/dbus) | D-Bus | yes | yes | system-config-services | no | - | no | | [Service bus API](https://www.freedesktop.org/wiki/Software/systemd/dbus) | D-Bus | yes | yes | system-config-services | no | - | no |
@ -94,14 +94,14 @@ And now, here's the list of (hopefully) all APIs that we have introduced with sy
| [$XDG_RUNTIME_DIR](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) | Environment | yes | yes | glib, GNOME | yes | - | no | | [$XDG_RUNTIME_DIR](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) | Environment | yes | yes | glib, GNOME | yes | - | no |
| [$LISTEN_FDS $LISTEN_PID FD Passing](https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html) | Environment | yes | yes | numerous (via sd-daemon.h) | yes | - | no | | [$LISTEN_FDS $LISTEN_PID FD Passing](https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html) | Environment | yes | yes | numerous (via sd-daemon.h) | yes | - | no |
| [$NOTIFY_SOCKET Daemon Notifications](https://www.freedesktop.org/software/systemd/man/sd_notify.html) | Environment | yes | yes | a few, including udev | yes | - | no | | [$NOTIFY_SOCKET Daemon Notifications](https://www.freedesktop.org/software/systemd/man/sd_notify.html) | Environment | yes | yes | a few, including udev | yes | - | no |
| [argv[0][0]='@' Logic](https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons) | `/proc` marking | yes | yes | mdadm | yes | - | no | | [argv[0][0]='@' Logic](https://systemd.io/ROOT_STORAGE_DAEMONS/) | `/proc` marking | yes | yes | mdadm | yes | - | no |
| [Unit file format](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) | File format | yes | yes | numerous | no | - | no | | [Unit file format](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) | File format | yes | yes | numerous | no | - | no |
| [Network](https://www.freedesktop.org/software/systemd/man/systemd.network.html) & [Netdev file format](https://www.freedesktop.org/software/systemd/man/systemd.netdev.html) | File format | yes | yes | no | no | - | no | | [Network](https://www.freedesktop.org/software/systemd/man/systemd.network.html) & [Netdev file format](https://www.freedesktop.org/software/systemd/man/systemd.netdev.html) | File format | yes | yes | no | no | - | no |
| [Link file format](https://www.freedesktop.org/software/systemd/man/systemd.link.html) | File format | yes | yes | no | no | - | no | | [Link file format](https://www.freedesktop.org/software/systemd/man/systemd.link.html) | File format | yes | yes | no | no | - | no |
| [Journal File Format](https://systemd.io/JOURNAL_FILE_FORMAT) | File format | yes | yes | - | maybe | - | no | | [Journal File Format](https://systemd.io/JOURNAL_FILE_FORMAT) | File format | yes | yes | - | maybe | - | no |
| [Journal Export Format](https://www.freedesktop.org/wiki/Software/systemd/export) | File format | yes | yes | - | yes | - | no | | [Journal Export Format](https://www.freedesktop.org/wiki/Software/systemd/export) | File format | yes | yes | - | yes | - | no |
| [Cooperation in cgroup tree](https://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups) | Treaty | yes | yes | libvirt | yes | libvirt | no | | [Cooperation in cgroup tree](https://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups) | Treaty | yes | yes | libvirt | yes | libvirt | no |
| [Password Agents](https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents) | Socket+Files | yes | yes | - | yes | - | no | | [Password Agents](https://systemd.io/PASSWORD_AGENTS/) | Socket+Files | yes | yes | - | yes | - | no |
| [udev multi-seat properties](https://www.freedesktop.org/wiki/Software/systemd/multiseat) | udev Property | yes | yes | X11, gdm | no | - | no | | [udev multi-seat properties](https://www.freedesktop.org/wiki/Software/systemd/multiseat) | udev Property | yes | yes | X11, gdm | no | - | no |
| udev session switch ACL properties | udev Property | no | no | - | no | - | no | | udev session switch ACL properties | udev Property | no | no | - | no | - | no |
| [CLI of systemctl,...](https://www.freedesktop.org/software/systemd/man/systemctl.html) | CLI | yes | yes | numerous | no | - | no | | [CLI of systemctl,...](https://www.freedesktop.org/software/systemd/man/systemctl.html) | CLI | yes | yes | numerous | no | - | no |

View File

@ -108,9 +108,9 @@ to find a different solution to your problem._
The recommended way to distinguish between run-from-initrd and run-from-rootfs The recommended way to distinguish between run-from-initrd and run-from-rootfs
for a daemon is to check for `/etc/initrd-release` (which exists on all modern for a daemon is to check for `/etc/initrd-release` (which exists on all modern
initrd implementations, see the [initrd initrd implementations, see the [initrd
Interface](http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface) Interface](https://systemd.io/INITRD_INTERFACE/) for details) which when exists
for details) which when exists results in `argv[0][0]` being set to `@`, and results in `argv[0][0]` being set to `@`, and otherwise doesn't. Something like
otherwise doesn't. Something like this: this:
```c ```c
#include <unistd.h> #include <unistd.h>

View File

@ -45,10 +45,9 @@
It is intended to be used after boot to ensure that users are It is intended to be used after boot to ensure that users are
properly notified.</para> properly notified.</para>
<para>See the <ulink <para>See the <ulink url="https://systemd.io/PASSWORD_AGENTS/">developer
url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents"> documentation</ulink> for more information about the system password logic.
developer documentation</ulink> for more information about the </para>
system password logic.</para>
<para>Note that these services invoke <para>Note that these services invoke
<citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry>

View File

@ -81,9 +81,8 @@
or similar.</para> or similar.</para>
<para>Additional password agents may be implemented according to <para>Additional password agents may be implemented according to
the <ulink the <ulink url="https://systemd.io/PASSWORD_AGENTS/">systemd Password Agent
url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd Specification</ulink>.</para>
Password Agent Specification</ulink>.</para>
<para>If a password is queried on a TTY, the user may press TAB to <para>If a password is queried on a TTY, the user may press TAB to
hide the asterisks normally shown for each character typed. hide the asterisks normally shown for each character typed.

View File

@ -36,10 +36,9 @@
<para><filename>systemd-cryptsetup@.service</filename> will ask <para><filename>systemd-cryptsetup@.service</filename> will ask
for hard disk passwords via the <ulink for hard disk passwords via the <ulink
url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents"> url="https://systemd.io/PASSWORD_AGENTS/">password agent logic</ulink>, in
password agent logic</ulink>, in order to query the user for the order to query the user for the password using the right mechanism at boot
password using the right mechanism at boot and during and during runtime.</para>
runtime.</para>
<para>At early boot and when the system manager configuration is reloaded, <filename>/etc/crypttab</filename> is <para>At early boot and when the system manager configuration is reloaded, <filename>/etc/crypttab</filename> is
translated into <filename>systemd-cryptsetup@.service</filename> units by translated into <filename>systemd-cryptsetup@.service</filename> units by

View File

@ -39,8 +39,8 @@
runtime.</para> runtime.</para>
<para><command>systemd-tty-ask-password-agent</command> implements <para><command>systemd-tty-ask-password-agent</command> implements
the <ulink url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">Password the <ulink url="https://systemd.io/PASSWORD_AGENTS/">Password Agents
Agents Specification</ulink>, and is one of many possible response agents which Specification</ulink>, and is one of many possible response agents which
answer to queries formulated with answer to queries formulated with
<citerefentry><refentrytitle>systemd-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>. <citerefentry><refentrytitle>systemd-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
</para> </para>

View File

@ -60,12 +60,14 @@
<filename>$XDG_RUNTIME_DIR/systemd/user.control/*</filename> <filename>$XDG_RUNTIME_DIR/systemd/user.control/*</filename>
<filename>$XDG_RUNTIME_DIR/systemd/transient/*</filename> <filename>$XDG_RUNTIME_DIR/systemd/transient/*</filename>
<filename>$XDG_RUNTIME_DIR/systemd/generator.early/*</filename> <filename>$XDG_RUNTIME_DIR/systemd/generator.early/*</filename>
<filename>~/.config/systemd/user/*</filename> <filename>$XDG_CONFIG_HOME/systemd/user/*</filename>
<filename>$XDG_CONFIG_DIRS/systemd/user/*</filename>
<filename>/etc/systemd/user/*</filename> <filename>/etc/systemd/user/*</filename>
<filename>$XDG_RUNTIME_DIR/systemd/user/*</filename> <filename>$XDG_RUNTIME_DIR/systemd/user/*</filename>
<filename>/run/systemd/user/*</filename> <filename>/run/systemd/user/*</filename>
<filename>$XDG_RUNTIME_DIR/systemd/generator/*</filename> <filename>$XDG_RUNTIME_DIR/systemd/generator/*</filename>
<filename>~/.local/share/systemd/user/*</filename> <filename>$XDG_DATA_HOME/systemd/user/*</filename>
<filename>$XDG_DATA_DIRS/systemd/user/*</filename>
<filename index='false'></filename> <filename index='false'></filename>
<filename>/usr/lib/systemd/user/*</filename> <filename>/usr/lib/systemd/user/*</filename>
<filename>$XDG_RUNTIME_DIR/systemd/generator.late/*</filename></literallayout></para> <filename>$XDG_RUNTIME_DIR/systemd/generator.late/*</filename></literallayout></para>
@ -255,9 +257,8 @@
start it even manually.</para> start it even manually.</para>
<para>The unit file format is covered by the <para>The unit file format is covered by the
<ulink <ulink url="https://systemd.io/PORTABILITY_AND_STABILITY/">Interface
url="https://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface Portability and Stability Promise</ulink>.</para>
Stability Promise</ulink>.</para>
</refsect1> </refsect1>
@ -435,6 +436,10 @@
<entry><filename>$XDG_CONFIG_HOME/systemd/user</filename> or <filename>$HOME/.config/systemd/user</filename></entry> <entry><filename>$XDG_CONFIG_HOME/systemd/user</filename> or <filename>$HOME/.config/systemd/user</filename></entry>
<entry>User configuration (<varname>$XDG_CONFIG_HOME</varname> is used if set, <filename>~/.config</filename> otherwise)</entry> <entry>User configuration (<varname>$XDG_CONFIG_HOME</varname> is used if set, <filename>~/.config</filename> otherwise)</entry>
</row> </row>
<row>
<entry><filename>$XDG_CONFIG_DIRS/systemd/user</filename> or <filename>/etc/xdg/systemd/user</filename></entry>
<entry>Additional configuration directories as specified by the XDG base directory specification (<varname>$XDG_CONFIG_DIRS</varname> is used if set, <filename>/etc/xdg</filename> otherwise)</entry>
</row>
<row> <row>
<entry><filename>/etc/systemd/user</filename></entry> <entry><filename>/etc/systemd/user</filename></entry>
<entry>User units created by the administrator</entry> <entry>User units created by the administrator</entry>
@ -456,6 +461,10 @@
<entry><filename>$XDG_DATA_HOME/systemd/user</filename> or <filename>$HOME/.local/share/systemd/user</filename></entry> <entry><filename>$XDG_DATA_HOME/systemd/user</filename> or <filename>$HOME/.local/share/systemd/user</filename></entry>
<entry>Units of packages that have been installed in the home directory (<varname>$XDG_DATA_HOME</varname> is used if set, <filename>~/.local/share</filename> otherwise)</entry> <entry>Units of packages that have been installed in the home directory (<varname>$XDG_DATA_HOME</varname> is used if set, <filename>~/.local/share</filename> otherwise)</entry>
</row> </row>
<row>
<entry><filename>$XDG_DATA_DIRS/systemd/user</filename> or <filename>/usr/local/share/systemd/user</filename> and <filename>/usr/share/systemd/user</filename></entry>
<entry>Additional data directories as specified by the XDG base directory specification (<varname>$XDG_DATA_DIRS</varname> is used if set, <filename>/usr/local/share</filename> and <filename>/usr/share</filename> otherwise)</entry>
</row>
<row> <row>
<entry><filename>$dir/systemd/user</filename> for each <varname index="false">$dir</varname> in <varname>$XDG_DATA_DIRS</varname></entry> <entry><filename>$dir/systemd/user</filename> for each <varname index="false">$dir</varname> in <varname>$XDG_DATA_DIRS</varname></entry>
<entry>Additional locations for installed user units, one for each entry in <varname>$XDG_DATA_DIRS</varname></entry> <entry>Additional locations for installed user units, one for each entry in <varname>$XDG_DATA_DIRS</varname></entry>

View File

@ -272,8 +272,7 @@
<para>Note that some but not all interfaces provided <para>Note that some but not all interfaces provided
by systemd are covered by the by systemd are covered by the
<ulink url="https://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface <ulink url="Portability and">Interface Portability and Stability Promise</ulink>.</para>
Stability Promise</ulink>.</para>
<para>Units may be generated dynamically at boot and system <para>Units may be generated dynamically at boot and system
manager reload time, for example based on other configuration manager reload time, for example based on other configuration
@ -287,8 +286,8 @@
</para> </para>
<para>Systems which invoke systemd in a container or initrd environment should implement the <ulink <para>Systems which invoke systemd in a container or initrd environment should implement the <ulink
url="https://systemd.io/CONTAINER_INTERFACE">Container Interface</ulink> or <ulink url="https://systemd.io/CONTAINER_INTERFACE">Container Interface</ulink> or
url="https://www.freedesktop.org/wiki/Software/systemd/InitrdInterface">initrd Interface</ulink> <ulink url="https://systemd.io/INITRD_INTERFACE/">initrd Interface</ulink>
specifications, respectively.</para> specifications, respectively.</para>
</refsect1> </refsect1>

View File

@ -181,10 +181,10 @@ static char** user_dirs(
if (strv_extend(&res, generator_early) < 0) if (strv_extend(&res, generator_early) < 0)
return NULL; return NULL;
if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0) if (strv_extend(&res, persistent_config) < 0)
return NULL; return NULL;
if (strv_extend(&res, persistent_config) < 0) if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
return NULL; return NULL;
/* global config has lower priority than the user config of the same type */ /* global config has lower priority than the user config of the same type */

View File

@ -260,7 +260,12 @@ finish:
dns_query_free(q); dns_query_free(q);
} }
static int validate_and_mangle_ifindex_and_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) { static int validate_and_mangle_flags(
const char *name,
uint64_t *flags,
uint64_t ok,
sd_bus_error *error) {
assert(flags); assert(flags);
/* Checks that the client supplied interface index and flags parameter actually are valid and make /* Checks that the client supplied interface index and flags parameter actually are valid and make
@ -277,15 +282,16 @@ static int validate_and_mangle_ifindex_and_flags(int ifindex, uint64_t *flags, u
* to mean "all supported protocols". * to mean "all supported protocols".
*/ */
if (ifindex < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok)) if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter"); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */ if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
*flags |= SD_RESOLVED_PROTOCOLS_ALL; *flags |= SD_RESOLVED_PROTOCOLS_ALL;
/* Imply SD_RESOLVED_NO_SEARCH if permitted and name is dot suffixed. */
if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0)
*flags |= SD_RESOLVED_NO_SEARCH;
return 0; return 0;
} }
@ -371,10 +377,13 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
if (r < 0) if (r < 0)
return r; return r;
if (ifindex < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC)) if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error); r = validate_and_mangle_flags(hostname, &flags, SD_RESOLVED_NO_SEARCH, error);
if (r < 0) if (r < 0)
return r; return r;
@ -527,7 +536,10 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s
if (r < 0) if (r < 0)
return r; return r;
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, 0, error); if (ifindex < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
r = validate_and_mangle_flags(NULL, &flags, 0, error);
if (r < 0) if (r < 0)
return r; return r;
@ -679,6 +691,9 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
if (r < 0) if (r < 0)
return r; return r;
if (ifindex < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
r = dns_name_is_valid(name); r = dns_name_is_valid(name);
if (r < 0) if (r < 0)
return r; return r;
@ -692,7 +707,7 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
if (dns_type_is_obsolete(type)) if (dns_type_is_obsolete(type))
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type); return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type);
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, 0, error); r = validate_and_mangle_flags(name, &flags, 0, error);
if (r < 0) if (r < 0)
return r; return r;
@ -1205,6 +1220,9 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
if (r < 0) if (r < 0)
return r; return r;
if (ifindex < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC)) if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
@ -1227,7 +1245,7 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
if (name && !type) if (name && !type)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type."); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error); r = validate_and_mangle_flags(name, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -93,7 +93,11 @@ static void vl_on_disconnect(VarlinkServer *s, Varlink *link, void *userdata) {
dns_query_complete(q, DNS_TRANSACTION_ABORTED); dns_query_complete(q, DNS_TRANSACTION_ABORTED);
} }
static bool validate_and_mangle_flags(uint64_t *flags, uint64_t ok) { static bool validate_and_mangle_flags(
const char *name,
uint64_t *flags,
uint64_t ok) {
assert(flags); assert(flags);
/* This checks that the specified client-provided flags parameter actually makes sense, and mangles /* This checks that the specified client-provided flags parameter actually makes sense, and mangles
@ -116,6 +120,12 @@ static bool validate_and_mangle_flags(uint64_t *flags, uint64_t ok) {
if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */ if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
*flags |= SD_RESOLVED_PROTOCOLS_ALL; *flags |= SD_RESOLVED_PROTOCOLS_ALL;
/* If the SD_RESOLVED_NO_SEARCH flag is acceptable, and the query name is dot-suffixed, turn off
* search domains. Note that DNS name normalization drops the dot suffix, hence we propagate this
* into the flags field as early as we can. */
if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0)
*flags |= SD_RESOLVED_NO_SEARCH;
return true; return true;
} }
@ -285,7 +295,7 @@ static int vl_method_resolve_hostname(Varlink *link, JsonVariant *parameters, Va
if (!IN_SET(p.family, AF_UNSPEC, AF_INET, AF_INET6)) if (!IN_SET(p.family, AF_UNSPEC, AF_INET, AF_INET6))
return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("family")); return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("family"));
if (!validate_and_mangle_flags(&p.flags, SD_RESOLVED_NO_SEARCH)) if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_SEARCH))
return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
r = parse_as_address(link, &p); r = parse_as_address(link, &p);
@ -460,7 +470,7 @@ static int vl_method_resolve_address(Varlink *link, JsonVariant *parameters, Var
if (FAMILY_ADDRESS_SIZE(p.family) != p.address_size) if (FAMILY_ADDRESS_SIZE(p.family) != p.address_size)
return varlink_error(link, "io.systemd.UserDatabase.BadAddressSize", NULL); return varlink_error(link, "io.systemd.UserDatabase.BadAddressSize", NULL);
if (!validate_and_mangle_flags(&p.flags, 0)) if (!validate_and_mangle_flags(NULL, &p.flags, 0))
return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags")); return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
r = dns_question_new_reverse(&question, p.family, &p.address); r = dns_question_new_reverse(&question, p.family, &p.address);

View File

@ -41,8 +41,9 @@ int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags f
/* Trailing dash */ /* Trailing dash */
return -EINVAL; return -EINVAL;
if (*n == '.') if (n[0] == '.' && (n[1] != 0 || !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT)))
n++; n++;
break; break;
} }
@ -139,7 +140,7 @@ int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags f
return -EINVAL; return -EINVAL;
/* More than one trailing dot? */ /* More than one trailing dot? */
if (*n == '.') if (n[0] == '.' && !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT))
return -EINVAL; return -EINVAL;
if (sz >= 1 && d) if (sz >= 1 && d)
@ -1372,3 +1373,19 @@ int dns_name_is_valid_or_address(const char *name) {
return dns_name_is_valid(name); return dns_name_is_valid(name);
} }
int dns_name_dot_suffixed(const char *name) {
const char *p = name;
int r;
for (;;) {
if (streq(p, "."))
return true;
r = dns_label_unescape(&p, NULL, DNS_LABEL_MAX, DNS_LABEL_LEAVE_TRAILING_DOT);
if (r < 0)
return r;
if (r == 0)
return false;
}
}

View File

@ -25,8 +25,9 @@
#define DNS_N_LABELS_MAX 127 #define DNS_N_LABELS_MAX 127
typedef enum DNSLabelFlags { typedef enum DNSLabelFlags {
DNS_LABEL_LDH = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */ DNS_LABEL_LDH = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */ DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */
DNS_LABEL_LEAVE_TRAILING_DOT = 1 << 2, /* Leave trailing dot in place */
} DNSLabelFlags; } DNSLabelFlags;
int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags); int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags);
@ -110,3 +111,5 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret);
int dns_name_apply_idna(const char *name, char **ret); int dns_name_apply_idna(const char *name, char **ret);
int dns_name_is_valid_or_address(const char *name); int dns_name_is_valid_or_address(const char *name);
int dns_name_dot_suffixed(const char *name);

View File

@ -780,6 +780,20 @@ static void test_dns_name_is_valid_or_address(void) {
assert_se(dns_name_is_valid_or_address("::1") > 0); assert_se(dns_name_is_valid_or_address("::1") > 0);
} }
static void test_dns_name_dot_suffixed(void) {
log_info("/* %s */", __func__);
assert_se(dns_name_dot_suffixed("") == 0);
assert_se(dns_name_dot_suffixed(".") > 0);
assert_se(dns_name_dot_suffixed("foo") == 0);
assert_se(dns_name_dot_suffixed("foo.") > 0);
assert_se(dns_name_dot_suffixed("foo\\..") > 0);
assert_se(dns_name_dot_suffixed("foo\\.") == 0);
assert_se(dns_name_dot_suffixed("foo.bar.") > 0);
assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\..") > 0);
assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\.\\.") == 0);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG); test_setup_logging(LOG_DEBUG);
@ -810,6 +824,7 @@ int main(int argc, char *argv[]) {
test_dns_name_common_suffix(); test_dns_name_common_suffix();
test_dns_name_apply_idna(); test_dns_name_apply_idna();
test_dns_name_is_valid_or_address(); test_dns_name_is_valid_or_address();
test_dns_name_dot_suffixed();
return 0; return 0;
} }

View File

@ -45,13 +45,14 @@ static int exec_list(sd_device_enumerator *e, const char *action, Set **settle_s
r = write_string_file(filename, action, WRITE_STRING_FILE_DISABLE_BUFFER); r = write_string_file(filename, action, WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0) { if (r < 0) {
bool ignore = IN_SET(r, -ENOENT, -EACCES, -ENODEV, -EROFS); bool ignore = r == -ENOENT;
log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r, log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
"Failed to write '%s' to '%s'%s: %m", "Failed to write '%s' to '%s'%s: %m",
action, filename, ignore ? ", ignoring" : ""); action, filename, ignore ? ", ignoring" : "");
if (r == -EROFS) if (IN_SET(r, -EACCES, -ENODEV, -EROFS))
return 0; /* Read only filesystem. Return earlier. */ /* Inovoked by unpriviledged user, or read only filesystem. Return earlier. */
return r;
if (ret == 0 && !ignore) if (ret == 0 && !ignore)
ret = r; ret = r;
continue; continue;