]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nss: do not modify errno when NSS_STATUS_NOTFOUND or NSS_STATUS_SUCCESS
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 15 Jul 2018 14:00:00 +0000 (23:00 +0900)
committerLennart Poettering <lennart@poettering.net>
Wed, 25 Jul 2018 08:23:22 +0000 (10:23 +0200)
This also adds PROTECT_ERRNO for all nss module functions.

C.f. glibc NSS documents https://www.gnu.org/software/libc/manual/html_node/NSS-Modules-Interface.html
and discussion in https://sourceware.org/bugzilla/show_bug.cgi?id=23410.

Fixes #9585.

src/nss-myhostname/nss-myhostname.c
src/nss-mymachines/nss-mymachines.c
src/nss-resolve/nss-resolve.c
src/nss-systemd/nss-systemd.c

index f82ce59f2cd04b270c29c2df02d5e9e63cfe3ec5..5abc0c91bf29a5f568bcc4d8741af00428326f54 100644 (file)
@@ -45,6 +45,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         char *r_name;
         unsigned n;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -64,7 +65,6 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
 
                 n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
                 if (n_addresses <= 0) {
-                        *errnop = ENOENT;
                         *h_errnop = HOST_NOT_FOUND;
                         return NSS_STATUS_NOTFOUND;
                 }
@@ -81,7 +81,6 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
 
                 /* We respond to our local host name, our hostname suffixed with a single dot. */
                 if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
-                        *errnop = ENOENT;
                         *h_errnop = HOST_NOT_FOUND;
                         return NSS_STATUS_NOTFOUND;
                 }
@@ -157,8 +156,8 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         if (ttlp)
                 *ttlp = 0;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
         *h_errnop = NETDB_SUCCESS;
         h_errno = 0;
 
@@ -286,8 +285,8 @@ static enum nss_status fill_in_hostent(
         if (canonp)
                 *canonp = r_name;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
         *h_errnop = NETDB_SUCCESS;
         h_errno = 0;
 
@@ -309,6 +308,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
         uint32_t local_address_ipv4 = 0;
         int n_addresses = 0;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -334,7 +334,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
 
                 n_addresses = local_gateways(NULL, 0, af, &addresses);
                 if (n_addresses <= 0) {
-                        *errnop = ENOENT;
                         *h_errnop = HOST_NOT_FOUND;
                         return NSS_STATUS_NOTFOUND;
                 }
@@ -350,7 +349,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
                 }
 
                 if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
-                        *errnop = ENOENT;
                         *h_errnop = HOST_NOT_FOUND;
                         return NSS_STATUS_NOTFOUND;
                 }
@@ -393,6 +391,7 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
         bool additional_from_hostname = false;
         unsigned n;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(addr);
@@ -455,7 +454,6 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
                 }
         }
 
-        *errnop = ENOENT;
         *h_errnop = HOST_NOT_FOUND;
         return NSS_STATUS_NOTFOUND;
 
index 8d6caa0ada97787aa94b0f78825583d8f48d2497..9b81cd9ad1602c8fa6a3ad10be1f605172d4bdb7 100644 (file)
@@ -80,6 +80,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
         char *r_name;
         int n_ifindices, r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -126,7 +127,6 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
                 goto fail;
 
         if (c <= 0) {
-                *errnop = ESRCH;
                 *h_errnop = HOST_NOT_FOUND;
                 return NSS_STATUS_NOTFOUND;
         }
@@ -200,8 +200,8 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
         if (ttlp)
                 *ttlp = 0;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
         *h_errnop = NETDB_SUCCESS;
         h_errno = 0;
 
@@ -230,6 +230,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
         size_t l, idx, ms, alen;
         int r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -278,7 +279,6 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
                 goto fail;
 
         if (c <= 0) {
-                *errnop = ENOENT;
                 *h_errnop = HOST_NOT_FOUND;
                 return NSS_STATUS_NOTFOUND;
         }
@@ -364,8 +364,8 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
         if (canonp)
                 *canonp = r_name;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
         *h_errnop = NETDB_SUCCESS;
         h_errno = 0;
 
@@ -394,6 +394,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
         size_t l;
         int r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -401,28 +402,28 @@ enum nss_status _nss_mymachines_getpwnam_r(
 
         p = startswith(name, "vu-");
         if (!p)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         e = strrchr(p, '-');
         if (!e || e == p)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         r = parse_uid(e + 1, &uid);
         if (r < 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         machine = strndupa(p, e - p);
         if (!machine_name_is_valid(machine))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
                 /* Make sure we can't deadlock if we are invoked by dbus-daemon. This way, it won't be able to resolve
                  * these UIDs, but that should be unproblematic as containers should never be able to connect to a bus
                  * running on the host. */
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         r = sd_bus_open_system(&bus);
         if (r < 0)
@@ -439,7 +440,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
                                machine, (uint32_t) uid);
         if (r < 0) {
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
 
                 goto fail;
         }
@@ -450,7 +451,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
 
         /* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */
         if (mapped < HOST_UID_LIMIT || mapped == uid)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         l = strlen(name);
         if (buflen < l+1) {
@@ -468,13 +469,8 @@ enum nss_status _nss_mymachines_getpwnam_r(
         pwd->pw_dir = (char*) "/";
         pwd->pw_shell = (char*) "/sbin/nologin";
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -493,17 +489,18 @@ enum nss_status _nss_mymachines_getpwuid_r(
         uint32_t mapped;
         int r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         if (!uid_is_valid(uid))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         /* We consider all uids < 65536 host uids */
         if (uid < HOST_UID_LIMIT)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         r = sd_bus_open_system(&bus);
         if (r < 0)
@@ -520,7 +517,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
                                (uint32_t) uid);
         if (r < 0) {
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
 
                 goto fail;
         }
@@ -530,7 +527,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
                 goto fail;
 
         if (mapped == uid)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) {
                 *errnop = ERANGE;
@@ -545,13 +542,8 @@ enum nss_status _nss_mymachines_getpwuid_r(
         pwd->pw_dir = (char*) "/";
         pwd->pw_shell = (char*) "/sbin/nologin";
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -574,6 +566,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
         size_t l;
         int r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -581,25 +574,25 @@ enum nss_status _nss_mymachines_getgrnam_r(
 
         p = startswith(name, "vg-");
         if (!p)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         e = strrchr(p, '-');
         if (!e || e == p)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (e - p > HOST_NAME_MAX - 1)  /* -1 for the last dash */
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         r = parse_gid(e + 1, &gid);
         if (r < 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         machine = strndupa(p, e - p);
         if (!machine_name_is_valid(machine))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         r = sd_bus_open_system(&bus);
         if (r < 0)
@@ -616,7 +609,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
                                machine, (uint32_t) gid);
         if (r < 0) {
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
 
                 goto fail;
         }
@@ -626,7 +619,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
                 goto fail;
 
         if (mapped < HOST_GID_LIMIT || mapped == gid)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         l = sizeof(char*) + strlen(name) + 1;
         if (buflen < l) {
@@ -642,13 +635,8 @@ enum nss_status _nss_mymachines_getgrnam_r(
         gr->gr_passwd = (char*) "*"; /* locked */
         gr->gr_mem = (char**) buffer;
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -667,17 +655,18 @@ enum nss_status _nss_mymachines_getgrgid_r(
         uint32_t mapped;
         int r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         if (!gid_is_valid(gid))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         /* We consider all gids < 65536 host gids */
         if (gid < HOST_GID_LIMIT)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         r = sd_bus_open_system(&bus);
         if (r < 0)
@@ -694,7 +683,7 @@ enum nss_status _nss_mymachines_getgrgid_r(
                                (uint32_t) gid);
         if (r < 0) {
                 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
 
                 goto fail;
         }
@@ -704,7 +693,7 @@ enum nss_status _nss_mymachines_getgrgid_r(
                 goto fail;
 
         if (mapped == gid)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (buflen < sizeof(char*) + 1) {
                 *errnop = ERANGE;
@@ -722,13 +711,8 @@ enum nss_status _nss_mymachines_getgrgid_r(
         gr->gr_passwd = (char*) "*"; /* locked */
         gr->gr_mem = (char**) buffer;
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
index eb3d2d977f45f42c764389c85ee03e8a5c76e9bb..b2bb698ded1c37e42b88a64f0ce3f3653d6a1d8f 100644 (file)
@@ -108,6 +108,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
         char *r_name;
         int c, r, i = 0;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -140,20 +141,15 @@ enum nss_status _nss_resolve_gethostbyname4_r(
 
         r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
         if (r < 0) {
-                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
-                        *errnop = ESRCH;
-                        *h_errnop = HOST_NOT_FOUND;
-                        return NSS_STATUS_NOTFOUND;
-                }
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
+                    !bus_error_shall_fallback(&error))
+                        goto not_found;
 
                 /* 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;
-
                 goto fail;
         }
 
@@ -162,11 +158,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
                 r = c;
                 goto fail;
         }
-        if (c == 0) {
-                *errnop = ESRCH;
-                *h_errnop = HOST_NOT_FOUND;
-                return NSS_STATUS_NOTFOUND;
-        }
+        if (c == 0)
+                goto not_found;
 
         if (isempty(canonical))
                 canonical = name;
@@ -247,8 +240,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
         if (ttlp)
                 *ttlp = 0;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
         *h_errnop = NETDB_SUCCESS;
         h_errno = 0;
 
@@ -258,6 +251,10 @@ fail:
         *errnop = -r;
         *h_errnop = NO_RECOVERY;
         return ret;
+
+not_found:
+        *h_errnop = HOST_NOT_FOUND;
+        return NSS_STATUS_NOTFOUND;
 }
 
 enum nss_status _nss_resolve_gethostbyname3_r(
@@ -278,6 +275,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
         const char *canonical;
         int c, r, i = 0;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -318,14 +316,9 @@ enum nss_status _nss_resolve_gethostbyname3_r(
 
         r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
         if (r < 0) {
-                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
-                        *errnop = ESRCH;
-                        *h_errnop = HOST_NOT_FOUND;
-                        return NSS_STATUS_NOTFOUND;
-                }
-
-                if (!bus_error_shall_fallback(&error))
-                        ret = NSS_STATUS_NOTFOUND;
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
+                    !bus_error_shall_fallback(&error))
+                        goto not_found;
 
                 goto fail;
         }
@@ -335,11 +328,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
                 r = c;
                 goto fail;
         }
-        if (c == 0) {
-                *errnop = ESRCH;
-                *h_errnop = HOST_NOT_FOUND;
-                return NSS_STATUS_NOTFOUND;
-        }
+        if (c == 0)
+                goto not_found;
 
         if (isempty(canonical))
                 canonical = name;
@@ -427,23 +417,27 @@ enum nss_status _nss_resolve_gethostbyname3_r(
         result->h_length = alen;
         result->h_addr_list = (char**) r_addr_list;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
-        *h_errnop = NETDB_SUCCESS;
-        h_errno = 0;
-
         if (ttlp)
                 *ttlp = 0;
 
         if (canonp)
                 *canonp = r_name;
 
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
+
         return NSS_STATUS_SUCCESS;
 
 fail:
         *errnop = -r;
         *h_errnop = NO_RECOVERY;
         return ret;
+
+not_found:
+        *h_errnop = HOST_NOT_FOUND;
+        return NSS_STATUS_NOTFOUND;
 }
 
 enum nss_status _nss_resolve_gethostbyaddr2_r(
@@ -464,6 +458,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
         const char *n;
         int r, ifindex;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(addr);
@@ -516,14 +511,9 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
 
         r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
         if (r < 0) {
-                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
-                        *errnop = ESRCH;
-                        *h_errnop = HOST_NOT_FOUND;
-                        return NSS_STATUS_NOTFOUND;
-                }
-
-                if (!bus_error_shall_fallback(&error))
-                        ret = NSS_STATUS_NOTFOUND;
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
+                    !bus_error_shall_fallback(&error))
+                        goto not_found;
 
                 goto fail;
         }
@@ -549,11 +539,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
         if (r < 0)
                 return r;
 
-        if (c <= 0) {
-                *errnop = ESRCH;
-                *h_errnop = HOST_NOT_FOUND;
-                return NSS_STATUS_NOTFOUND;
-        }
+        if (c <= 0)
+                goto not_found;
 
         ms += ALIGN(len) +              /* the address */
               2 * sizeof(char*) +       /* pointers to the address, plus trailing NULL */
@@ -612,8 +599,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
         if (ttlp)
                 *ttlp = 0;
 
-        /* Explicitly reset all error variables */
-        *errnop = 0;
+        /* Explicitly reset both *h_errnop and h_errno to work around
+         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
         *h_errnop = NETDB_SUCCESS;
         h_errno = 0;
 
@@ -623,6 +610,10 @@ fail:
         *errnop = -r;
         *h_errnop = NO_RECOVERY;
         return ret;
+
+not_found:
+        *h_errnop = HOST_NOT_FOUND;
+        return NSS_STATUS_NOTFOUND;
 }
 
 NSS_GETHOSTBYNAME_FALLBACKS(resolve);
index f516b84c63891be7e4695bcb26603da643a74399..f554828d49a60963544a49b0db70696df983d713 100644 (file)
@@ -145,6 +145,7 @@ enum nss_status _nss_systemd_getpwnam_r(
         size_t l;
         int bypass, r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
@@ -153,26 +154,24 @@ enum nss_status _nss_systemd_getpwnam_r(
         /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't
          * generate EINVAL here, because it isn't really out business to complain about invalid user names. */
         if (!valid_user_group_name(name))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         /* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
                 if (streq(name, root_passwd.pw_name)) {
                         *pwd = root_passwd;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
                 if (synthesize_nobody() &&
                     streq(name, nobody_passwd.pw_name)) {
                         *pwd = nobody_passwd;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
         }
 
         /* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
         if (bypass <= 0) {
@@ -184,7 +183,7 @@ enum nss_status _nss_systemd_getpwnam_r(
         if (bypass > 0) {
                 r = direct_lookup_name(name, (uid_t*) &translated);
                 if (r == -ENOENT)
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
                 if (r < 0)
                         goto fail;
         } else {
@@ -199,7 +198,7 @@ enum nss_status _nss_systemd_getpwnam_r(
                                        name);
                 if (r < 0) {
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
-                                goto not_found;
+                                return NSS_STATUS_NOTFOUND;
 
                         goto fail;
                 }
@@ -225,13 +224,8 @@ enum nss_status _nss_systemd_getpwnam_r(
         pwd->pw_dir = (char*) DYNAMIC_USER_DIR;
         pwd->pw_shell = (char*) DYNAMIC_USER_SHELL;
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -251,31 +245,30 @@ enum nss_status _nss_systemd_getpwuid_r(
         size_t l;
         int bypass, r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         if (!uid_is_valid(uid))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         /* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
                 if (uid == root_passwd.pw_uid) {
                         *pwd = root_passwd;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
                 if (synthesize_nobody() &&
                     uid == nobody_passwd.pw_uid) {
                         *pwd = nobody_passwd;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
         }
 
         if (!uid_is_dynamic(uid))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
         if (bypass <= 0) {
@@ -287,7 +280,7 @@ enum nss_status _nss_systemd_getpwuid_r(
         if (bypass > 0) {
                 r = direct_lookup_uid(uid, &direct);
                 if (r == -ENOENT)
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
                 if (r < 0)
                         goto fail;
 
@@ -305,7 +298,7 @@ enum nss_status _nss_systemd_getpwuid_r(
                                        (uint32_t) uid);
                 if (r < 0) {
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
-                                goto not_found;
+                                return NSS_STATUS_NOTFOUND;
 
                         goto fail;
                 }
@@ -331,13 +324,8 @@ enum nss_status _nss_systemd_getpwuid_r(
         pwd->pw_dir = (char*) DYNAMIC_USER_DIR;
         pwd->pw_shell = (char*) DYNAMIC_USER_SHELL;
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -358,31 +346,30 @@ enum nss_status _nss_systemd_getgrnam_r(
         size_t l;
         int bypass, r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(name);
         assert(gr);
 
         if (!valid_user_group_name(name))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         /* Synthesize records for root and nobody, in case they are missing form /etc/group */
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
                 if (streq(name, root_group.gr_name)) {
                         *gr = root_group;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
                 if (synthesize_nobody() &&
                     streq(name, nobody_group.gr_name)) {
                         *gr = nobody_group;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
         }
 
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
         if (bypass <= 0) {
@@ -394,7 +381,7 @@ enum nss_status _nss_systemd_getgrnam_r(
         if (bypass > 0) {
                 r = direct_lookup_name(name, (uid_t*) &translated);
                 if (r == -ENOENT)
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
                 if (r < 0)
                         goto fail;
         } else {
@@ -409,7 +396,7 @@ enum nss_status _nss_systemd_getgrnam_r(
                                        name);
                 if (r < 0) {
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
-                                goto not_found;
+                                return NSS_STATUS_NOTFOUND;
 
                         goto fail;
                 }
@@ -433,13 +420,8 @@ enum nss_status _nss_systemd_getgrnam_r(
         gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD;
         gr->gr_mem = (char**) buffer;
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -459,31 +441,30 @@ enum nss_status _nss_systemd_getgrgid_r(
         size_t l;
         int bypass, r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         if (!gid_is_valid(gid))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         /* Synthesize records for root and nobody, in case they are missing from /etc/group */
         if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
                 if (gid == root_group.gr_gid) {
                         *gr = root_group;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
                 if (synthesize_nobody() &&
                     gid == nobody_group.gr_gid) {
                         *gr = nobody_group;
-                        *errnop = 0;
                         return NSS_STATUS_SUCCESS;
                 }
         }
 
         if (!gid_is_dynamic(gid))
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         if (getenv_bool_secure("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
-                goto not_found;
+                return NSS_STATUS_NOTFOUND;
 
         bypass = getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS");
         if (bypass <= 0) {
@@ -495,7 +476,7 @@ enum nss_status _nss_systemd_getgrgid_r(
         if (bypass > 0) {
                 r = direct_lookup_uid(gid, &direct);
                 if (r == -ENOENT)
-                        goto not_found;
+                        return NSS_STATUS_NOTFOUND;
                 if (r < 0)
                         goto fail;
 
@@ -513,7 +494,7 @@ enum nss_status _nss_systemd_getgrgid_r(
                                        (uint32_t) gid);
                 if (r < 0) {
                         if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_DYNAMIC_USER))
-                                goto not_found;
+                                return NSS_STATUS_NOTFOUND;
 
                         goto fail;
                 }
@@ -537,13 +518,8 @@ enum nss_status _nss_systemd_getgrgid_r(
         gr->gr_passwd = (char*) DYNAMIC_USER_PASSWD;
         gr->gr_mem = (char**) buffer;
 
-        *errnop = 0;
         return NSS_STATUS_SUCCESS;
 
-not_found:
-        *errnop = 0;
-        return NSS_STATUS_NOTFOUND;
-
 fail:
         *errnop = -r;
         return NSS_STATUS_UNAVAIL;
@@ -598,6 +574,7 @@ static void systemd_endent(GetentData *data) {
 }
 
 static enum nss_status nss_systemd_endent(GetentData *p) {
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert_se(pthread_mutex_lock(&p->mutex) == 0);
@@ -668,6 +645,7 @@ static enum nss_status systemd_setent(GetentData *p) {
         uid_t id;
         int bypass, r;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(p);
@@ -750,6 +728,7 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz
         UserEntry *p;
         size_t len;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(result);
@@ -778,7 +757,6 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz
                 break;
         }
         if (!p) {
-                *errnop = ENOENT;
                 ret = NSS_STATUS_NOTFOUND;
                 goto finalize;
         }
@@ -801,6 +779,7 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size
         UserEntry *p;
         size_t len;
 
+        PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
         assert(result);
@@ -827,7 +806,6 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size
                 break;
         }
         if (!p) {
-                *errnop = ENOENT;
                 ret = NSS_STATUS_NOTFOUND;
                 goto finalize;
         }