958 lines
32 KiB
Diff
958 lines
32 KiB
Diff
From 34bb0461192c9feba0c0f05a8baf8fefcd9d835e Mon Sep 17 00:00:00 2001
|
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
Date: Sun, 15 Jul 2018 23:00:00 +0900
|
|
Subject: [PATCH] nss: do not modify errno when NSS_STATUS_NOTFOUND or
|
|
NSS_STATUS_SUCCESS
|
|
|
|
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.
|
|
|
|
(cherry picked from commit 06202b9e659e5cc72aeecc5200155b7c012fccbc)
|
|
|
|
Resolves: #1691691
|
|
---
|
|
src/nss-myhostname/nss-myhostname.c | 16 +++---
|
|
src/nss-mymachines/nss-mymachines.c | 88 ++++++++++++-----------------
|
|
src/nss-resolve/nss-resolve.c | 87 +++++++++++++---------------
|
|
src/nss-systemd/nss-systemd.c | 74 +++++++++---------------
|
|
4 files changed, 108 insertions(+), 157 deletions(-)
|
|
|
|
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
|
|
index f82ce59f2c..5abc0c91bf 100644
|
|
--- a/src/nss-myhostname/nss-myhostname.c
|
|
+++ b/src/nss-myhostname/nss-myhostname.c
|
|
@@ -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;
|
|
|
|
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
|
|
index 8d6caa0ada..9b81cd9ad1 100644
|
|
--- a/src/nss-mymachines/nss-mymachines.c
|
|
+++ b/src/nss-mymachines/nss-mymachines.c
|
|
@@ -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;
|
|
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
|
|
index eb3d2d977f..b2bb698ded 100644
|
|
--- a/src/nss-resolve/nss-resolve.c
|
|
+++ b/src/nss-resolve/nss-resolve.c
|
|
@@ -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);
|
|
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
|
|
index f516b84c63..f554828d49 100644
|
|
--- a/src/nss-systemd/nss-systemd.c
|
|
+++ b/src/nss-systemd/nss-systemd.c
|
|
@@ -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;
|
|
}
|