From 414b63a0e65eaac65a755dd65fc9bcceb0314655 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mantas=20Mikul=C4=97nas?= <grawity@gmail.com>
Date: Wed, 21 Jul 2021 08:50:09 +0300
Subject: [PATCH] NSS client: avoid using NETDB_INTERNAL if daemon is not
 available

It seems that returning NETDB_INTERNAL as h_errno will cause glibc's
getaddrinfo() to immediately return EAI_SYSTEM *without* falling through
to other configured NSS modules.

This means that if /etc/nsswitch.conf has 'sss' listed before 'dns' (for
example), hostname resolution will be completely broken whenever SSSD is
not running.

(Even hostname lookups done by SSSD itself will fail, as the _SSS_LOOPS
environment variable merely forces errno=0 but the getaddrinfo() call as
a whole still returns EAI_SYSTEM.)

This commit makes the NSS client return h_errno=NO_RECOVERY, as that's
what systemd's nss-resolve and nss-mymachines seem to be doing.
---
 src/sss_client/nss_hosts.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/sss_client/nss_hosts.c b/src/sss_client/nss_hosts.c
index aa26762865..59fe82e595 100644
--- a/src/sss_client/nss_hosts.c
+++ b/src/sss_client/nss_hosts.c
@@ -250,7 +250,7 @@ internal_gethostbyname2_r(const char *name, int af,
     nret = sss_nss_make_request(SSS_NSS_GETHOSTBYNAME2, &rd,
                                 &repbuf, &replen, errnop);
     if (nret != NSS_STATUS_SUCCESS) {
-        *h_errnop = NETDB_INTERNAL;
+        *h_errnop = NO_RECOVERY;
         goto out;
     }
 
@@ -380,7 +380,7 @@ _nss_sss_gethostbyaddr_r(const void *addr, socklen_t addrlen,
                                 &repbuf, &replen, errnop);
     free(data);
     if (nret != NSS_STATUS_SUCCESS) {
-        *h_errnop = NETDB_INTERNAL;
+        *h_errnop = NO_RECOVERY;
         goto out;
     }
 
@@ -500,7 +500,7 @@ internal_gethostent_r(struct hostent *result,
     nret = sss_nss_make_request(SSS_NSS_GETHOSTENT, &rd,
                                 &repbuf, &replen, errnop);
     if (nret != NSS_STATUS_SUCCESS) {
-        *h_errnop = NETDB_INTERNAL;
+        *h_errnop = NO_RECOVERY;
         return nret;
     }
 
