]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/sysusers/sysusers.c
sysusers: also add support for NIS entries in /etc/shadow
[thirdparty/systemd.git] / src / sysusers / sysusers.c
index 5dcc213b1710ce6b22ee389b35759f708d13ac59..0af4af06aadd6a25a8e441254a9e43362dfb258f 100644 (file)
@@ -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)