1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-30 14:55:37 +03:00

sysusers: do not append entries after the NIS ones

The NIS-catchall entry switches from files to NIS lookup and never goes back,
so it must be the last entry in /etc/passwd (the other +/-{user,@netgroup}
entries don't have to be).

That's how the nss_compat mode for /etc/passwd (and /etc/group) traditionally
works.

It's age-old historic behaviour that the NIS entry must be the last one.  It
doesn't seem to be specified somewhere, but it worked like this since very
early SunOS when NIS was first included.

Fixes: #8467
This commit is contained in:
Franck Bui 2018-03-15 18:46:28 +01:00
parent 848e863acc
commit 563dc6f8e2

View File

@ -396,6 +396,7 @@ static const char* default_shell(uid_t uid) {
static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char **tmpfile_path) {
_cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
_cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
struct passwd *pw = NULL;
Iterator iterator;
Item *i;
int r;
@ -409,7 +410,6 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
original = fopen(passwd_path, "re");
if (original) {
struct passwd *pw;
r = sync_rights(original, passwd);
if (r < 0)
@ -429,6 +429,10 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
return -EEXIST;
}
/* Make sure we keep the NIS entries (if any) at the end. */
if (IN_SET(pw->pw_name[0], '+', '-'))
break;
errno = 0;
if (putpwent(pw, passwd) < 0)
return errno ? -errno : -EIO;
@ -468,6 +472,17 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char
return errno ? -errno : -EIO;
}
/* Append the remaining NIS entries if any */
while (pw) {
errno = 0;
if (putpwent(pw, passwd) < 0)
return errno ? -errno : -EIO;
pw = fgetpwent(original);
}
if (!IN_SET(errno, 0, ENOENT))
return -errno;
r = fflush_and_check(passwd);
if (r < 0)
return r;
@ -567,6 +582,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
_cleanup_fclose_ FILE *original = NULL, *group = NULL;
_cleanup_(unlink_and_freep) char *group_tmp = NULL;
bool group_changed = false;
struct group *gr = NULL;
Iterator iterator;
Item *i;
int r;
@ -580,7 +596,6 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
original = fopen(group_path, "re");
if (original) {
struct group *gr;
r = sync_rights(original, group);
if (r < 0)
@ -604,6 +619,10 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
return -EEXIST;
}
/* Make sure we keep the NIS entries (if any) at the end. */
if (IN_SET(gr->gr_name[0], '+', '-'))
break;
r = putgrent_with_members(gr, group);
if (r < 0)
return r;
@ -636,6 +655,17 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char **
group_changed = true;
}
/* Append the remaining NIS entries if any */
while (gr) {
errno = 0;
if (putgrent(gr, group) != 0)
return errno > 0 ? -errno : -EIO;
gr = fgetgrent(original);
}
if (!IN_SET(errno, 0, ENOENT))
return -errno;
r = fflush_sync_and_check(group);
if (r < 0)
return r;