summaryrefslogtreecommitdiff
path: root/src/nss-systemd
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-07-15 23:00:00 +0900
committerLennart Poettering <lennart@poettering.net>2018-07-25 10:23:22 +0200
commit06202b9e659e5cc72aeecc5200155b7c012fccbc (patch)
tree7a22eef18632b21c764e1d446a21b8a3054f326b /src/nss-systemd
parent8d455017eedfe7e67f7fa5db9939c35b9e4dcf60 (diff)
downloadsystemd-06202b9e659e5cc72aeecc5200155b7c012fccbc.tar.gz
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.
Diffstat (limited to 'src/nss-systemd')
-rw-r--r--src/nss-systemd/nss-systemd.c74
1 files changed, 26 insertions, 48 deletions
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;
}