nss-systemd,sysusers: make sure sysusers doesn't get confused by nss-systemd (#6812)

In nss-systemd we synthesize user entries for "nobody" and "root", as
fallback if we boot up with an entirely empty /etc. This is supposed to
be a fallback only though, and it's intended that both users exists
regularly in /etc/passwd + /etc/group. Before this patch
systemd-sysusers would never create the entries however as it notices
the synthetic entries. Let's add a way how systemd-sysusers can tell
nss-systemd not to synthesize the entries for itself.

Fixes: #6808
This commit is contained in:
Lennart Poettering 2017-09-14 06:20:39 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent d5df18e4b6
commit fe102d6ab1
2 changed files with 54 additions and 36 deletions

View file

@ -129,15 +129,17 @@ enum nss_status _nss_systemd_getpwnam_r(
goto not_found;
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
if (streq(name, root_passwd.pw_name)) {
*pwd = root_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (streq(name, nobody_passwd.pw_name)) {
*pwd = nobody_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
if (getenv_bool("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (streq(name, root_passwd.pw_name)) {
*pwd = root_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (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 */
@ -231,15 +233,17 @@ enum nss_status _nss_systemd_getpwuid_r(
goto not_found;
/* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */
if (uid == root_passwd.pw_uid) {
*pwd = root_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (uid == nobody_passwd.pw_uid) {
*pwd = nobody_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
if (getenv_bool("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (uid == root_passwd.pw_uid) {
*pwd = root_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (uid == nobody_passwd.pw_uid) {
*pwd = nobody_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
}
if (uid <= SYSTEM_UID_MAX)
@ -331,15 +335,17 @@ enum nss_status _nss_systemd_getgrnam_r(
goto not_found;
/* Synthesize records for root and nobody, in case they are missing form /etc/group */
if (streq(name, root_group.gr_name)) {
*gr = root_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (streq(name, nobody_group.gr_name)) {
*gr = nobody_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
if (getenv_bool("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (streq(name, root_group.gr_name)) {
*gr = root_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (streq(name, nobody_group.gr_name)) {
*gr = nobody_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
}
if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
@ -430,15 +436,17 @@ enum nss_status _nss_systemd_getgrgid_r(
goto not_found;
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
if (gid == root_group.gr_gid) {
*gr = root_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (gid == nobody_group.gr_gid) {
*gr = nobody_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
if (getenv_bool("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (gid == root_group.gr_gid) {
*gr = root_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
if (gid == nobody_group.gr_gid) {
*gr = nobody_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
}
if (gid <= SYSTEM_GID_MAX)

View file

@ -1811,6 +1811,16 @@ int main(int argc, char *argv[]) {
}
}
/* Let's tell nss-systemd not to synthesize the "root" and "nobody" entries for it, so that our detection
* whether the names or UID/GID area already used otherwise doesn't get confused. After all, even though
* nss-systemd synthesizes these users/groups, they should still appear in /etc/passwd and /etc/group, as the
* synthesizing logic is merely supposed to be fallback for cases where we run with a completely unpopulated
* /etc. */
if (setenv("SYSTEMD_NSS_BYPASS_SYNTHETIC", "1", 1) < 0) {
r = log_error_errno(errno, "Failed to set SYSTEMD_NSS_BYPASS_SYNTHETIC environment variable: %m");
goto finish;
}
if (!uid_range) {
/* Default to default range of 1..SYSTEMD_UID_MAX */
r = uid_range_add(&uid_range, &n_uid_range, 1, SYSTEM_UID_MAX);