diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-05-12 08:31:46 -0400 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-05-12 14:31:46 +0200 |
commit | 5486a31d287f26bcd7c0a4eb2abfa4c074b985f1 (patch) | |
tree | d1e644d972fe60531ab0e17be6deb6c86941ad75 /src/nss-resolve/nss-resolve.c | |
parent | 3823da25cf0d374851321d0c5fa5bce872ef5f2b (diff) | |
download | systemd-5486a31d287f26bcd7c0a4eb2abfa4c074b985f1.tar.gz |
nss-resolve: drop the internal fallback to libnss_dns (#5945)
If we could not communicate with systemd-resolved, we would call into
libnss_dns. libnss_dns would return NOTFOUND for stuff like "localhost" and
other names resolved by nss-myhostname, which we would fall under the !UNAVAIL=
condition and cause resolution to fail. So the following recommended
configuration in nsswitch.conf would not work:
hosts: resolve [!UNAVAIL=return] dns myhostname
Remove the internal fallback code completely so that the fallback logic
can be configured in nsswitch.conf.
Tested with
hosts: resolve [!UNAVAIL=return] myhostname
and
hosts: resolve [!UNAVAIL=return] dns myhostname
Fixes #5742.
Diffstat (limited to 'src/nss-resolve/nss-resolve.c')
-rw-r--r-- | src/nss-resolve/nss-resolve.c | 76 |
1 files changed, 14 insertions, 62 deletions
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c index d155625e11..ec059d9586 100644 --- a/src/nss-resolve/nss-resolve.c +++ b/src/nss-resolve/nss-resolve.c @@ -17,7 +17,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <dlfcn.h> #include <errno.h> #include <netdb.h> #include <nss.h> @@ -39,20 +38,6 @@ NSS_GETHOSTBYADDR_PROTOTYPES(resolve); #define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC) -typedef void (*voidfunc_t)(void); - -static voidfunc_t find_fallback(const char *module, const char *symbol) { - void *dl; - - /* Try to find a fallback NSS module symbol */ - - dl = dlopen(module, RTLD_LAZY|RTLD_NODELETE); - if (!dl) - return NULL; - - return dlsym(dl, symbol); -} - static bool bus_error_shall_fallback(sd_bus_error *e) { return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) || sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) || @@ -151,7 +136,7 @@ enum nss_status _nss_resolve_gethostbyname4_r( r = sd_bus_open_system(&bus); if (r < 0) - goto fallback; + goto fail; r = sd_bus_message_new_method_call( bus, @@ -179,13 +164,14 @@ enum nss_status _nss_resolve_gethostbyname4_r( return NSS_STATUS_NOTFOUND; } - if (bus_error_shall_fallback(&error)) - goto fallback; + /* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails, + allowing falling back to other nss modules. Treat all other error conditions as + NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this + case so that the nsswitch.conf configuration can distuingish such executed but + negative replies from complete failure to talk to resolved). */ + if (!bus_error_shall_fallback(&error)) + ret = NSS_STATUS_NOTFOUND; - /* Treat all other error conditions as NOTFOUND, and fail. This includes DNSSEC errors and - suchlike. (We don't use UNAVAIL in this case so that the nsswitch.conf configuration can distuingish - such executed but negative replies from complete failure to talk to resolved. */ - ret = NSS_STATUS_NOTFOUND; goto fail; } @@ -286,17 +272,6 @@ enum nss_status _nss_resolve_gethostbyname4_r( return NSS_STATUS_SUCCESS; -fallback: - { - _nss_gethostbyname4_r_t fallback; - - fallback = (_nss_gethostbyname4_r_t) - find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r"); - - if (fallback) - return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp); - } - fail: *errnop = -r; *h_errnop = NO_RECOVERY; @@ -339,7 +314,7 @@ enum nss_status _nss_resolve_gethostbyname3_r( r = sd_bus_open_system(&bus); if (r < 0) - goto fallback; + goto fail; r = sd_bus_message_new_method_call( bus, @@ -367,10 +342,9 @@ enum nss_status _nss_resolve_gethostbyname3_r( return NSS_STATUS_NOTFOUND; } - if (bus_error_shall_fallback(&error)) - goto fallback; + if (!bus_error_shall_fallback(&error)) + ret = NSS_STATUS_NOTFOUND; - ret = NSS_STATUS_NOTFOUND; goto fail; } @@ -484,16 +458,6 @@ enum nss_status _nss_resolve_gethostbyname3_r( return NSS_STATUS_SUCCESS; -fallback: - { - _nss_gethostbyname3_r_t fallback; - - fallback = (_nss_gethostbyname3_r_t) - find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r"); - if (fallback) - return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp); - } - fail: *errnop = -r; *h_errnop = NO_RECOVERY; @@ -540,7 +504,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( r = sd_bus_open_system(&bus); if (r < 0) - goto fallback; + goto fail; r = sd_bus_message_new_method_call( bus, @@ -576,10 +540,9 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( return NSS_STATUS_NOTFOUND; } - if (bus_error_shall_fallback(&error)) - goto fallback; + if (!bus_error_shall_fallback(&error)) + ret = NSS_STATUS_NOTFOUND; - ret = NSS_STATUS_NOTFOUND; goto fail; } @@ -674,17 +637,6 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( return NSS_STATUS_SUCCESS; -fallback: - { - _nss_gethostbyaddr2_r_t fallback; - - fallback = (_nss_gethostbyaddr2_r_t) - find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r"); - - if (fallback) - return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp); - } - fail: *errnop = -r; *h_errnop = NO_RECOVERY; |