nss-resolve: be a bit more careful with returning NSS_STATUS_NOTFOUND
authorLennart Poettering <lennart@poettering.net>
Mon, 24 Oct 2016 16:50:43 +0000 (18:50 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 24 Oct 2016 17:04:43 +0000 (19:04 +0200)
Let's tighten the cases when our module returns NSS_STATUS_NOTFOUND. Let's do
so only if we actually managed to talk to resolved. In all other cases stick to
NSS_STATUS_UNAVAIL as before, as it clearly indicates that our module or the
system is borked, and the "dns" fallback should really take place.

In particular this fixes the 2nd-level fallback from our own dlopen() based
fallback handling. In this case we really should return UNAVAIL so that the
caller can apply its own fallback still.

Fix-up for d7247512a904f1dd74125859d8da66166c2a6933.

Note that our own dlopen() based fallback is pretty much redundant now if
nsswitch.conf is configured like this:

   hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname

In a future release we should probably drop our internal fallback then, in
favour of this nsswitch.conf-based one.

src/nss-resolve/nss-resolve.c

index eea91e3..d46a3af 100644 (file)
@@ -121,6 +121,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+        enum nss_status ret = NSS_STATUS_UNAVAIL;
         const char *canonical = NULL;
         size_t l, ms, idx;
         char *r_name;
@@ -167,6 +168,10 @@ enum nss_status _nss_resolve_gethostbyname4_r(
                 if (bus_error_shall_fallback(&error))
                         goto fallback;
 
+                /* 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;
         }
 
@@ -279,12 +284,9 @@ fallback:
         }
 
 fail:
-        /* When we arrive here, resolved runs and has answered (fallback to
-         * "dns" is handled earlier). So we have a definitive "no" answer and
-         * should not fall back to subsequent NSS modules via "UNAVAIL". */
         *errnop = -r;
         *h_errnop = NO_RECOVERY;
-        return NSS_STATUS_NOTFOUND;
+        return ret;
 }
 
 enum nss_status _nss_resolve_gethostbyname3_r(
@@ -300,6 +302,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         char *r_name, *r_aliases, *r_addr, *r_addr_list;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+        enum nss_status ret = NSS_STATUS_UNAVAIL;
         size_t l, idx, ms, alen;
         const char *canonical;
         int c, r, i = 0;
@@ -353,6 +356,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
                 if (bus_error_shall_fallback(&error))
                         goto fallback;
 
+                ret = NSS_STATUS_NOTFOUND;
                 goto fail;
         }
 
@@ -479,7 +483,7 @@ fallback:
 fail:
         *errnop = -r;
         *h_errnop = NO_RECOVERY;
-        return NSS_STATUS_NOTFOUND;
+        return ret;
 }
 
 enum nss_status _nss_resolve_gethostbyaddr2_r(
@@ -494,6 +498,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         char *r_name, *r_aliases, *r_addr, *r_addr_list;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+        enum nss_status ret = NSS_STATUS_UNAVAIL;
         unsigned c = 0, i = 0;
         size_t ms = 0, idx;
         const char *n;
@@ -560,7 +565,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
                 if (bus_error_shall_fallback(&error))
                         goto fallback;
 
-
+                ret = NSS_STATUS_NOTFOUND;
                 goto fail;
         }
 
@@ -669,7 +674,7 @@ fallback:
 fail:
         *errnop = -r;
         *h_errnop = NO_RECOVERY;
-        return NSS_STATUS_NOTFOUND;
+        return ret;
 }
 
 NSS_GETHOSTBYNAME_FALLBACKS(resolve);