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