From 19ec7de2d65ad01a76a2f8672363e72c43607934 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Tue, 20 Mar 2018 09:32:05 +0100 Subject: [PATCH 1/2] sysusers: also add support for NIS entries in /etc/shadow Commit 563dc6f8e2cda4114dd20f32655890ed378c3740 added support for /etc/{passwd,group} only but since nsswitch.conf(5) appears to document the NIS entries also for shadow, let's support this case too. --- src/sysusers/sysusers.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 5dcc213b17..0af4af06aa 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -497,6 +497,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char **tmpfile_path) { _cleanup_fclose_ FILE *original = NULL, *shadow = NULL; _cleanup_(unlink_and_freep) char *shadow_tmp = NULL; + struct spwd *sp = NULL; Iterator iterator; long lstchg; Item *i; @@ -513,7 +514,6 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char original = fopen(shadow_path, "re"); if (original) { - struct spwd *sp; r = sync_rights(original, shadow); if (r < 0) @@ -534,6 +534,11 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char } errno = 0; + + /* Make sure we keep the NIS entries (if any) at the end. */ + if (IN_SET(sp->sp_namp[0], '+', '-')) + break; + if (putspent(sp, shadow) < 0) return errno ? -errno : -EIO; @@ -566,6 +571,19 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char if (putspent(&n, shadow) != 0) return errno ? -errno : -EIO; } + errno = 0; + + /* Append the remaining NIS entries if any */ + while (sp) { + errno = 0; + if (putspent(sp, shadow) < 0) + return errno ? -errno : -EIO; + + errno = 0; + sp = fgetspent(original); + } + if (!IN_SET(errno, 0, ENOENT)) + return -errno; r = fflush_sync_and_check(shadow); if (r < 0) From 8c1b45aa9cc0241bdf2c143df493ddf2596ae8b1 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Tue, 20 Mar 2018 11:38:00 +0100 Subject: [PATCH 2/2] sysusers: make sure to reset errno before calling fget*ent() Due to the glibc interface we have to test errno in various places to detect if an error occured after calling fget*ent() helpers. --- src/sysusers/sysusers.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 0af4af06aa..43952e5f19 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -429,11 +429,12 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char return -EEXIST; } + errno = 0; + /* 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; @@ -471,6 +472,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char if (putpwent(&n, passwd) != 0) return errno ? -errno : -EIO; } + errno = 0; /* Append the remaining NIS entries if any */ while (pw) { @@ -478,6 +480,7 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char if (putpwent(pw, passwd) < 0) return errno ? -errno : -EIO; + errno = 0; pw = fgetpwent(original); } if (!IN_SET(errno, 0, ENOENT)) @@ -637,6 +640,8 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** return -EEXIST; } + errno = 0; + /* Make sure we keep the NIS entries (if any) at the end. */ if (IN_SET(gr->gr_name[0], '+', '-')) break; @@ -672,6 +677,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** group_changed = true; } + errno = 0; /* Append the remaining NIS entries if any */ while (gr) { @@ -679,6 +685,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** if (putgrent(gr, group) != 0) return errno > 0 ? -errno : -EIO; + errno = 0; gr = fgetgrent(original); } if (!IN_SET(errno, 0, ENOENT))