Blame SOURCES/0121-nss-do-not-modify-errno-when-NSS_STATUS_NOTFOUND-or-.patch

a3e2b5
From 34bb0461192c9feba0c0f05a8baf8fefcd9d835e Mon Sep 17 00:00:00 2001
a3e2b5
From: Yu Watanabe <watanabe.yu+github@gmail.com>
a3e2b5
Date: Sun, 15 Jul 2018 23:00:00 +0900
a3e2b5
Subject: [PATCH] nss: do not modify errno when NSS_STATUS_NOTFOUND or
a3e2b5
 NSS_STATUS_SUCCESS
a3e2b5
a3e2b5
This also adds PROTECT_ERRNO for all nss module functions.
a3e2b5
a3e2b5
C.f. glibc NSS documents https://www.gnu.org/software/libc/manual/html_node/NSS-Modules-Interface.html
a3e2b5
and discussion in https://sourceware.org/bugzilla/show_bug.cgi?id=23410.
a3e2b5
a3e2b5
Fixes #9585.
a3e2b5
a3e2b5
(cherry picked from commit 06202b9e659e5cc72aeecc5200155b7c012fccbc)
a3e2b5
a3e2b5
Resolves: #1691691
a3e2b5
---
a3e2b5
 src/nss-myhostname/nss-myhostname.c | 16 +++---
a3e2b5
 src/nss-mymachines/nss-mymachines.c | 88 ++++++++++++-----------------
a3e2b5
 src/nss-resolve/nss-resolve.c       | 87 +++++++++++++---------------
a3e2b5
 src/nss-systemd/nss-systemd.c       | 74 +++++++++---------------
a3e2b5
 4 files changed, 108 insertions(+), 157 deletions(-)
a3e2b5
a3e2b5
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
a3e2b5
index f82ce59f2c..5abc0c91bf 100644
a3e2b5
--- a/src/nss-myhostname/nss-myhostname.c
a3e2b5
+++ b/src/nss-myhostname/nss-myhostname.c
a3e2b5
@@ -45,6 +45,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
a3e2b5
         char *r_name;
a3e2b5
         unsigned n;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -64,7 +65,6 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
a3e2b5
 
a3e2b5
                 n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
a3e2b5
                 if (n_addresses <= 0) {
a3e2b5
-                        *errnop = ENOENT;
a3e2b5
                         *h_errnop = HOST_NOT_FOUND;
a3e2b5
                         return NSS_STATUS_NOTFOUND;
a3e2b5
                 }
a3e2b5
@@ -81,7 +81,6 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
a3e2b5
 
a3e2b5
                 /* We respond to our local host name, our hostname suffixed with a single dot. */
a3e2b5
                 if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
a3e2b5
-                        *errnop = ENOENT;
a3e2b5
                         *h_errnop = HOST_NOT_FOUND;
a3e2b5
                         return NSS_STATUS_NOTFOUND;
a3e2b5
                 }
a3e2b5
@@ -157,8 +156,8 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
a3e2b5
         if (ttlp)
a3e2b5
                 *ttlp = 0;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
         *h_errnop = NETDB_SUCCESS;
a3e2b5
         h_errno = 0;
a3e2b5
 
a3e2b5
@@ -286,8 +285,8 @@ static enum nss_status fill_in_hostent(
a3e2b5
         if (canonp)
a3e2b5
                 *canonp = r_name;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
         *h_errnop = NETDB_SUCCESS;
a3e2b5
         h_errno = 0;
a3e2b5
 
a3e2b5
@@ -309,6 +308,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
a3e2b5
         uint32_t local_address_ipv4 = 0;
a3e2b5
         int n_addresses = 0;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -334,7 +334,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
a3e2b5
 
a3e2b5
                 n_addresses = local_gateways(NULL, 0, af, &addresses);
a3e2b5
                 if (n_addresses <= 0) {
a3e2b5
-                        *errnop = ENOENT;
a3e2b5
                         *h_errnop = HOST_NOT_FOUND;
a3e2b5
                         return NSS_STATUS_NOTFOUND;
a3e2b5
                 }
a3e2b5
@@ -350,7 +349,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
a3e2b5
                 }
a3e2b5
 
a3e2b5
                 if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
a3e2b5
-                        *errnop = ENOENT;
a3e2b5
                         *h_errnop = HOST_NOT_FOUND;
a3e2b5
                         return NSS_STATUS_NOTFOUND;
a3e2b5
                 }
a3e2b5
@@ -393,6 +391,7 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
a3e2b5
         bool additional_from_hostname = false;
a3e2b5
         unsigned n;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(addr);
a3e2b5
@@ -455,7 +454,6 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
a3e2b5
                 }
a3e2b5
         }
a3e2b5
 
a3e2b5
-        *errnop = ENOENT;
a3e2b5
         *h_errnop = HOST_NOT_FOUND;
a3e2b5
         return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
a3e2b5
index 8d6caa0ada..9b81cd9ad1 100644
a3e2b5
--- a/src/nss-mymachines/nss-mymachines.c
a3e2b5
+++ b/src/nss-mymachines/nss-mymachines.c
a3e2b5
@@ -80,6 +80,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
a3e2b5
         char *r_name;
a3e2b5
         int n_ifindices, r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -126,7 +127,6 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
a3e2b5
                 goto fail;
a3e2b5
 
a3e2b5
         if (c <= 0) {
a3e2b5
-                *errnop = ESRCH;
a3e2b5
                 *h_errnop = HOST_NOT_FOUND;
a3e2b5
                 return NSS_STATUS_NOTFOUND;
a3e2b5
         }
a3e2b5
@@ -200,8 +200,8 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
a3e2b5
         if (ttlp)
a3e2b5
                 *ttlp = 0;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
         *h_errnop = NETDB_SUCCESS;
a3e2b5
         h_errno = 0;
a3e2b5
 
a3e2b5
@@ -230,6 +230,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
a3e2b5
         size_t l, idx, ms, alen;
a3e2b5
         int r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -278,7 +279,6 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
a3e2b5
                 goto fail;
a3e2b5
 
a3e2b5
         if (c <= 0) {
a3e2b5
-                *errnop = ENOENT;
a3e2b5
                 *h_errnop = HOST_NOT_FOUND;
a3e2b5
                 return NSS_STATUS_NOTFOUND;
a3e2b5
         }
a3e2b5
@@ -364,8 +364,8 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
a3e2b5
         if (canonp)
a3e2b5
                 *canonp = r_name;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
         *h_errnop = NETDB_SUCCESS;
a3e2b5
         h_errno = 0;
a3e2b5
 
a3e2b5
@@ -394,6 +394,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
         size_t l;
a3e2b5
         int r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -401,28 +402,28 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
 
a3e2b5
         p = startswith(name, "vu-");
a3e2b5
         if (!p)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         e = strrchr(p, '-');
a3e2b5
         if (!e || e == p)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         r = parse_uid(e + 1, &uid);
a3e2b5
         if (r < 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         machine = strndupa(p, e - p);
a3e2b5
         if (!machine_name_is_valid(machine))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
a3e2b5
                 /* Make sure we can't deadlock if we are invoked by dbus-daemon. This way, it won't be able to resolve
a3e2b5
                  * these UIDs, but that should be unproblematic as containers should never be able to connect to a bus
a3e2b5
                  * running on the host. */
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         r = sd_bus_open_system(&bus;;
a3e2b5
         if (r < 0)
a3e2b5
@@ -439,7 +440,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
                                machine, (uint32_t) uid);
a3e2b5
         if (r < 0) {
a3e2b5
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
@@ -450,7 +451,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
 
a3e2b5
         /* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */
a3e2b5
         if (mapped < HOST_UID_LIMIT || mapped == uid)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         l = strlen(name);
a3e2b5
         if (buflen < l+1) {
a3e2b5
@@ -468,13 +469,8 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
         pwd->pw_dir = (char*) "/";
a3e2b5
         pwd->pw_shell = (char*) "/sbin/nologin";
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -493,17 +489,18 @@ enum nss_status _nss_mymachines_getpwuid_r(
a3e2b5
         uint32_t mapped;
a3e2b5
         int r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         if (!uid_is_valid(uid))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         /* We consider all uids < 65536 host uids */
a3e2b5
         if (uid < HOST_UID_LIMIT)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         r = sd_bus_open_system(&bus;;
a3e2b5
         if (r < 0)
a3e2b5
@@ -520,7 +517,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
a3e2b5
                                (uint32_t) uid);
a3e2b5
         if (r < 0) {
a3e2b5
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
@@ -530,7 +527,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
a3e2b5
                 goto fail;
a3e2b5
 
a3e2b5
         if (mapped == uid)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) {
a3e2b5
                 *errnop = ERANGE;
a3e2b5
@@ -545,13 +542,8 @@ enum nss_status _nss_mymachines_getpwuid_r(
a3e2b5
         pwd->pw_dir = (char*) "/";
a3e2b5
         pwd->pw_shell = (char*) "/sbin/nologin";
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -574,6 +566,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
         size_t l;
a3e2b5
         int r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -581,25 +574,25 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
 
a3e2b5
         p = startswith(name, "vg-");
a3e2b5
         if (!p)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         e = strrchr(p, '-');
a3e2b5
         if (!e || e == p)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (e - p > HOST_NAME_MAX - 1)  /* -1 for the last dash */
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         r = parse_gid(e + 1, &gid;;
a3e2b5
         if (r < 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         machine = strndupa(p, e - p);
a3e2b5
         if (!machine_name_is_valid(machine))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         r = sd_bus_open_system(&bus;;
a3e2b5
         if (r < 0)
a3e2b5
@@ -616,7 +609,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
                                machine, (uint32_t) gid);
a3e2b5
         if (r < 0) {
a3e2b5
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
@@ -626,7 +619,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
                 goto fail;
a3e2b5
 
a3e2b5
         if (mapped < HOST_GID_LIMIT || mapped == gid)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         l = sizeof(char*) + strlen(name) + 1;
a3e2b5
         if (buflen < l) {
a3e2b5
@@ -642,13 +635,8 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
         gr->gr_passwd = (char*) "*"; /* locked */
a3e2b5
         gr->gr_mem = (char**) buffer;
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -667,17 +655,18 @@ enum nss_status _nss_mymachines_getgrgid_r(
a3e2b5
         uint32_t mapped;
a3e2b5
         int r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         if (!gid_is_valid(gid))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         /* We consider all gids < 65536 host gids */
a3e2b5
         if (gid < HOST_GID_LIMIT)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         r = sd_bus_open_system(&bus;;
a3e2b5
         if (r < 0)
a3e2b5
@@ -694,7 +683,7 @@ enum nss_status _nss_mymachines_getgrgid_r(
a3e2b5
                                (uint32_t) gid);
a3e2b5
         if (r < 0) {
a3e2b5
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
@@ -704,7 +693,7 @@ enum nss_status _nss_mymachines_getgrgid_r(
a3e2b5
                 goto fail;
a3e2b5
 
a3e2b5
         if (mapped == gid)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (buflen < sizeof(char*) + 1) {
a3e2b5
                 *errnop = ERANGE;
a3e2b5
@@ -722,13 +711,8 @@ enum nss_status _nss_mymachines_getgrgid_r(
a3e2b5
         gr->gr_passwd = (char*) "*"; /* locked */
a3e2b5
         gr->gr_mem = (char**) buffer;
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
a3e2b5
index eb3d2d977f..b2bb698ded 100644
a3e2b5
--- a/src/nss-resolve/nss-resolve.c
a3e2b5
+++ b/src/nss-resolve/nss-resolve.c
a3e2b5
@@ -108,6 +108,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
a3e2b5
         char *r_name;
a3e2b5
         int c, r, i = 0;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -140,20 +141,15 @@ enum nss_status _nss_resolve_gethostbyname4_r(
a3e2b5
 
a3e2b5
         r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
a3e2b5
         if (r < 0) {
a3e2b5
-                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
a3e2b5
-                        *errnop = ESRCH;
a3e2b5
-                        *h_errnop = HOST_NOT_FOUND;
a3e2b5
-                        return NSS_STATUS_NOTFOUND;
a3e2b5
-                }
a3e2b5
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
a3e2b5
+                    !bus_error_shall_fallback(&error))
a3e2b5
+                        goto not_found;
a3e2b5
 
a3e2b5
                 /* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails,
a3e2b5
                    allowing falling back to other nss modules. Treat all other error conditions as
a3e2b5
                    NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this
a3e2b5
                    case so that the nsswitch.conf configuration can distuingish such executed but
a3e2b5
                    negative replies from complete failure to talk to resolved). */
a3e2b5
-                if (!bus_error_shall_fallback(&error))
a3e2b5
-                        ret = NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
 
a3e2b5
@@ -162,11 +158,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
a3e2b5
                 r = c;
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
-        if (c == 0) {
a3e2b5
-                *errnop = ESRCH;
a3e2b5
-                *h_errnop = HOST_NOT_FOUND;
a3e2b5
-                return NSS_STATUS_NOTFOUND;
a3e2b5
-        }
a3e2b5
+        if (c == 0)
a3e2b5
+                goto not_found;
a3e2b5
 
a3e2b5
         if (isempty(canonical))
a3e2b5
                 canonical = name;
a3e2b5
@@ -247,8 +240,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
a3e2b5
         if (ttlp)
a3e2b5
                 *ttlp = 0;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
         *h_errnop = NETDB_SUCCESS;
a3e2b5
         h_errno = 0;
a3e2b5
 
a3e2b5
@@ -258,6 +251,10 @@ fail:
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_RECOVERY;
a3e2b5
         return ret;
a3e2b5
+
a3e2b5
+not_found:
a3e2b5
+        *h_errnop = HOST_NOT_FOUND;
a3e2b5
+        return NSS_STATUS_NOTFOUND;
a3e2b5
 }
a3e2b5
 
a3e2b5
 enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
@@ -278,6 +275,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
         const char *canonical;
a3e2b5
         int c, r, i = 0;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -318,14 +316,9 @@ enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
 
a3e2b5
         r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
a3e2b5
         if (r < 0) {
a3e2b5
-                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
a3e2b5
-                        *errnop = ESRCH;
a3e2b5
-                        *h_errnop = HOST_NOT_FOUND;
a3e2b5
-                        return NSS_STATUS_NOTFOUND;
a3e2b5
-                }
a3e2b5
-
a3e2b5
-                if (!bus_error_shall_fallback(&error))
a3e2b5
-                        ret = NSS_STATUS_NOTFOUND;
a3e2b5
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
a3e2b5
+                    !bus_error_shall_fallback(&error))
a3e2b5
+                        goto not_found;
a3e2b5
 
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
@@ -335,11 +328,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
                 r = c;
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
-        if (c == 0) {
a3e2b5
-                *errnop = ESRCH;
a3e2b5
-                *h_errnop = HOST_NOT_FOUND;
a3e2b5
-                return NSS_STATUS_NOTFOUND;
a3e2b5
-        }
a3e2b5
+        if (c == 0)
a3e2b5
+                goto not_found;
a3e2b5
 
a3e2b5
         if (isempty(canonical))
a3e2b5
                 canonical = name;
a3e2b5
@@ -427,23 +417,27 @@ enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
         result->h_length = alen;
a3e2b5
         result->h_addr_list = (char**) r_addr_list;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
-        *h_errnop = NETDB_SUCCESS;
a3e2b5
-        h_errno = 0;
a3e2b5
-
a3e2b5
         if (ttlp)
a3e2b5
                 *ttlp = 0;
a3e2b5
 
a3e2b5
         if (canonp)
a3e2b5
                 *canonp = r_name;
a3e2b5
 
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
+        *h_errnop = NETDB_SUCCESS;
a3e2b5
+        h_errno = 0;
a3e2b5
+
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_RECOVERY;
a3e2b5
         return ret;
a3e2b5
+
a3e2b5
+not_found:
a3e2b5
+        *h_errnop = HOST_NOT_FOUND;
a3e2b5
+        return NSS_STATUS_NOTFOUND;
a3e2b5
 }
a3e2b5
 
a3e2b5
 enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
@@ -464,6 +458,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
         const char *n;
a3e2b5
         int r, ifindex;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(addr);
a3e2b5
@@ -516,14 +511,9 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
 
a3e2b5
         r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
a3e2b5
         if (r < 0) {
a3e2b5
-                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
a3e2b5
-                        *errnop = ESRCH;
a3e2b5
-                        *h_errnop = HOST_NOT_FOUND;
a3e2b5
-                        return NSS_STATUS_NOTFOUND;
a3e2b5
-                }
a3e2b5
-
a3e2b5
-                if (!bus_error_shall_fallback(&error))
a3e2b5
-                        ret = NSS_STATUS_NOTFOUND;
a3e2b5
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
a3e2b5
+                    !bus_error_shall_fallback(&error))
a3e2b5
+                        goto not_found;
a3e2b5
 
a3e2b5
                 goto fail;
a3e2b5
         }
a3e2b5
@@ -549,11 +539,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
         if (r < 0)
a3e2b5
                 return r;
a3e2b5
 
a3e2b5
-        if (c <= 0) {
a3e2b5
-                *errnop = ESRCH;
a3e2b5
-                *h_errnop = HOST_NOT_FOUND;
a3e2b5
-                return NSS_STATUS_NOTFOUND;
a3e2b5
-        }
a3e2b5
+        if (c <= 0)
a3e2b5
+                goto not_found;
a3e2b5
 
a3e2b5
         ms += ALIGN(len) +              /* the address */
a3e2b5
               2 * sizeof(char*) +       /* pointers to the address, plus trailing NULL */
a3e2b5
@@ -612,8 +599,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
         if (ttlp)
a3e2b5
                 *ttlp = 0;
a3e2b5
 
a3e2b5
-        /* Explicitly reset all error variables */
a3e2b5
-        *errnop = 0;
a3e2b5
+        /* Explicitly reset both *h_errnop and h_errno to work around
a3e2b5
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
a3e2b5
         *h_errnop = NETDB_SUCCESS;
a3e2b5
         h_errno = 0;
a3e2b5
 
a3e2b5
@@ -623,6 +610,10 @@ fail:
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_RECOVERY;
a3e2b5
         return ret;
a3e2b5
+
a3e2b5
+not_found:
a3e2b5
+        *h_errnop = HOST_NOT_FOUND;
a3e2b5
+        return NSS_STATUS_NOTFOUND;
a3e2b5
 }
a3e2b5
 
a3e2b5
 NSS_GETHOSTBYNAME_FALLBACKS(resolve);
a3e2b5
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
a3e2b5
index f516b84c63..f554828d49 100644
a3e2b5
--- a/src/nss-systemd/nss-systemd.c
a3e2b5
+++ b/src/nss-systemd/nss-systemd.c
a3e2b5
@@ -145,6 +145,7 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
         size_t l;
a3e2b5
         int bypass, r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
@@ -153,26 +154,24 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
         /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't
a3e2b5
          * generate EINVAL here, because it isn't really out business to complain about invalid user names. */
a3e2b5
         if (!valid_user_group_name(name))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         /* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
a3e2b5
                 if (streq(name, root_passwd.pw_name)) {
a3e2b5
                         *pwd = root_passwd;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
                 if (synthesize_nobody() &&
a3e2b5
                     streq(name, nobody_passwd.pw_name)) {
a3e2b5
                         *pwd = nobody_passwd;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
         }
a3e2b5
 
a3e2b5
         /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
a3e2b5
         if (bypass <= 0) {
a3e2b5
@@ -184,7 +183,7 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
         if (bypass > 0) {
a3e2b5
                 r = direct_lookup_name(name, (uid_t*) &translated);
a3e2b5
                 if (r == -ENOENT)
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
                 if (r < 0)
a3e2b5
                         goto fail;
a3e2b5
         } else {
a3e2b5
@@ -199,7 +198,7 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
                                        name);
a3e2b5
                 if (r < 0) {
a3e2b5
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
a3e2b5
-                                goto not_found;
a3e2b5
+                                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                         goto fail;
a3e2b5
                 }
a3e2b5
@@ -225,13 +224,8 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
         pwd->pw_dir = (char*) DYNAMIC_USER_DIR;
a3e2b5
         pwd->pw_shell = (char*) DYNAMIC_USER_SHELL;
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -251,31 +245,30 @@ enum nss_status _nss_systemd_getpwuid_r(
a3e2b5
         size_t l;
a3e2b5
         int bypass, r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         if (!uid_is_valid(uid))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         /* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
a3e2b5
                 if (uid == root_passwd.pw_uid) {
a3e2b5
                         *pwd = root_passwd;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
                 if (synthesize_nobody() &&
a3e2b5
                     uid == nobody_passwd.pw_uid) {
a3e2b5
                         *pwd = nobody_passwd;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
         }
a3e2b5
 
a3e2b5
         if (!uid_is_dynamic(uid))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
a3e2b5
         if (bypass <= 0) {
a3e2b5
@@ -287,7 +280,7 @@ enum nss_status _nss_systemd_getpwuid_r(
a3e2b5
         if (bypass > 0) {
a3e2b5
                 r = direct_lookup_uid(uid, &direct);
a3e2b5
                 if (r == -ENOENT)
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
                 if (r < 0)
a3e2b5
                         goto fail;
a3e2b5
 
a3e2b5
@@ -305,7 +298,7 @@ enum nss_status _nss_systemd_getpwuid_r(
a3e2b5
                                        (uint32_t) uid);
a3e2b5
                 if (r < 0) {
a3e2b5
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
a3e2b5
-                                goto not_found;
a3e2b5
+                                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                         goto fail;
a3e2b5
                 }
a3e2b5
@@ -331,13 +324,8 @@ enum nss_status _nss_systemd_getpwuid_r(
a3e2b5
         pwd->pw_dir = (char*) DYNAMIC_USER_DIR;
a3e2b5
         pwd->pw_shell = (char*) DYNAMIC_USER_SHELL;
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -358,31 +346,30 @@ enum nss_status _nss_systemd_getgrnam_r(
a3e2b5
         size_t l;
a3e2b5
         int bypass, r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(name);
a3e2b5
         assert(gr);
a3e2b5
 
a3e2b5
         if (!valid_user_group_name(name))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         /* Synthesize records for root and nobody, in case they are missing form /etc/group */
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
a3e2b5
                 if (streq(name, root_group.gr_name)) {
a3e2b5
                         *gr = root_group;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
                 if (synthesize_nobody() &&
a3e2b5
                     streq(name, nobody_group.gr_name)) {
a3e2b5
                         *gr = nobody_group;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
         }
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
a3e2b5
         if (bypass <= 0) {
a3e2b5
@@ -394,7 +381,7 @@ enum nss_status _nss_systemd_getgrnam_r(
a3e2b5
         if (bypass > 0) {
a3e2b5
                 r = direct_lookup_name(name, (uid_t*) &translated);
a3e2b5
                 if (r == -ENOENT)
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
                 if (r < 0)
a3e2b5
                         goto fail;
a3e2b5
         } else {
a3e2b5
@@ -409,7 +396,7 @@ enum nss_status _nss_systemd_getgrnam_r(
a3e2b5
                                        name);
a3e2b5
                 if (r < 0) {
a3e2b5
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
a3e2b5
-                                goto not_found;
a3e2b5
+                                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                         goto fail;
a3e2b5
                 }
a3e2b5
@@ -433,13 +420,8 @@ enum nss_status _nss_systemd_getgrnam_r(
a3e2b5
         gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD;
a3e2b5
         gr->gr_mem = (char**) buffer;
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -459,31 +441,30 @@ enum nss_status _nss_systemd_getgrgid_r(
a3e2b5
         size_t l;
a3e2b5
         int bypass, r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         if (!gid_is_valid(gid))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         /* Synthesize records for root and nobody, in case they are missing from /etc/group */
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
a3e2b5
                 if (gid == root_group.gr_gid) {
a3e2b5
                         *gr = root_group;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
                 if (synthesize_nobody() &&
a3e2b5
                     gid == nobody_group.gr_gid) {
a3e2b5
                         *gr = nobody_group;
a3e2b5
-                        *errnop = 0;
a3e2b5
                         return NSS_STATUS_SUCCESS;
a3e2b5
                 }
a3e2b5
         }
a3e2b5
 
a3e2b5
         if (!gid_is_dynamic(gid))
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
a3e2b5
-                goto not_found;
a3e2b5
+                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
a3e2b5
         if (bypass <= 0) {
a3e2b5
@@ -495,7 +476,7 @@ enum nss_status _nss_systemd_getgrgid_r(
a3e2b5
         if (bypass > 0) {
a3e2b5
                 r = direct_lookup_uid(gid, &direct);
a3e2b5
                 if (r == -ENOENT)
a3e2b5
-                        goto not_found;
a3e2b5
+                        return NSS_STATUS_NOTFOUND;
a3e2b5
                 if (r < 0)
a3e2b5
                         goto fail;
a3e2b5
 
a3e2b5
@@ -513,7 +494,7 @@ enum nss_status _nss_systemd_getgrgid_r(
a3e2b5
                                        (uint32_t) gid);
a3e2b5
                 if (r < 0) {
a3e2b5
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
a3e2b5
-                                goto not_found;
a3e2b5
+                                return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
                         goto fail;
a3e2b5
                 }
a3e2b5
@@ -537,13 +518,8 @@ enum nss_status _nss_systemd_getgrgid_r(
a3e2b5
         gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD;
a3e2b5
         gr->gr_mem = (char**) buffer;
a3e2b5
 
a3e2b5
-        *errnop = 0;
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
-not_found:
a3e2b5
-        *errnop = 0;
a3e2b5
-        return NSS_STATUS_NOTFOUND;
a3e2b5
-
a3e2b5
 fail:
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -598,6 +574,7 @@ static void systemd_endent(GetentData *data) {
a3e2b5
 }
a3e2b5
 
a3e2b5
 static enum nss_status nss_systemd_endent(GetentData *p) {
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert_se(pthread_mutex_lock(&p->mutex) == 0);
a3e2b5
@@ -668,6 +645,7 @@ static enum nss_status systemd_setent(GetentData *p) {
a3e2b5
         uid_t id;
a3e2b5
         int bypass, r;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(p);
a3e2b5
@@ -750,6 +728,7 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz
a3e2b5
         UserEntry *p;
a3e2b5
         size_t len;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(result);
a3e2b5
@@ -778,7 +757,6 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz
a3e2b5
                 break;
a3e2b5
         }
a3e2b5
         if (!p) {
a3e2b5
-                *errnop = ENOENT;
a3e2b5
                 ret = NSS_STATUS_NOTFOUND;
a3e2b5
                 goto finalize;
a3e2b5
         }
a3e2b5
@@ -801,6 +779,7 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size
a3e2b5
         UserEntry *p;
a3e2b5
         size_t len;
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
a3e2b5
 
a3e2b5
         assert(result);
a3e2b5
@@ -827,7 +806,6 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size
a3e2b5
                 break;
a3e2b5
         }
a3e2b5
         if (!p) {
a3e2b5
-                *errnop = ENOENT;
a3e2b5
                 ret = NSS_STATUS_NOTFOUND;
a3e2b5
                 goto finalize;
a3e2b5
         }