mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-28 03:25:27 +03:00
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.
This commit is contained in:
parent
8d455017ee
commit
06202b9e65
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user