803fb7
From 169e74d772eac561a24f461ac65118d3d83a5980 Mon Sep 17 00:00:00 2001
803fb7
From: Ivan Shapovalov <intelfx100@gmail.com>
803fb7
Date: Sat, 7 Mar 2015 18:11:32 +0300
803fb7
Subject: [PATCH] sysusers: do not reject users with already present
803fb7
 /etc/shadow entries
803fb7
803fb7
This is needed to interoperate firstboot and sysusers. The former one is started
803fb7
first, and it writes only /etc/shadow when it is told to set the root password.
803fb7
It's better to relax checks here than to duplicate functionality in firstboot.
803fb7
803fb7
(cherry picked from commit c5abf22514b3925aa6f0d4a3f36f76799bf1911b)
803fb7
---
803fb7
 src/sysusers/sysusers.c | 23 +++++++++--------------
803fb7
 1 file changed, 9 insertions(+), 14 deletions(-)
803fb7
803fb7
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
803fb7
index e47bcb4dc..76b5962c5 100644
803fb7
--- a/src/sysusers/sysusers.c
803fb7
+++ b/src/sysusers/sysusers.c
803fb7
@@ -605,6 +605,8 @@ static int write_files(void) {
803fb7
                 if (r < 0)
803fb7
                         goto finish;
803fb7
 
803fb7
+                lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
803fb7
+
803fb7
                 original = fopen(shadow_path, "re");
803fb7
                 if (original) {
803fb7
                         struct spwd *sp;
803fb7
@@ -618,8 +620,13 @@ static int write_files(void) {
803fb7
 
803fb7
                                 i = hashmap_get(users, sp->sp_namp);
803fb7
                                 if (i && i->todo_user) {
803fb7
-                                        r = -EEXIST;
803fb7
-                                        goto finish;
803fb7
+                                        /* we will update the existing entry */
803fb7
+                                        sp->sp_lstchg = lstchg;
803fb7
+
803fb7
+                                        /* only the /etc/shadow stage is left, so we can
803fb7
+                                         * safely remove the item from the todo set */
803fb7
+                                        i->todo_user = false;
803fb7
+                                        hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
803fb7
                                 }
803fb7
 
803fb7
                                 errno = 0;
803fb7
@@ -642,7 +649,6 @@ static int write_files(void) {
803fb7
                         goto finish;
803fb7
                 }
803fb7
 
803fb7
-                lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
803fb7
                 HASHMAP_FOREACH(i, todo_uids, iterator) {
803fb7
                         struct spwd n = {
803fb7
                                 .sp_namp = i->name,
803fb7
@@ -879,7 +885,6 @@ static int add_user(Item *i) {
803fb7
 
803fb7
         if (!arg_root) {
803fb7
                 struct passwd *p;
803fb7
-                struct spwd *sp;
803fb7
 
803fb7
                 /* Also check NSS */
803fb7
                 errno = 0;
803fb7
@@ -895,16 +900,6 @@ static int add_user(Item *i) {
803fb7
                 }
803fb7
                 if (!IN_SET(errno, 0, ENOENT))
803fb7
                         return log_error_errno(errno, "Failed to check if user %s already exists: %m", i->name);
803fb7
-
803fb7
-                /* And shadow too, just to be sure */
803fb7
-                errno = 0;
803fb7
-                sp = getspnam(i->name);
803fb7
-                if (sp) {
803fb7
-                        log_error("User %s already exists in shadow database, but not in user database.", i->name);
803fb7
-                        return -EBADMSG;
803fb7
-                }
803fb7
-                if (!IN_SET(errno, 0, ENOENT))
803fb7
-                        return log_error_errno(errno, "Failed to check if user %s already exists in shadow database: %m", i->name);
803fb7
         }
803fb7
 
803fb7
         /* Try to use the suggested numeric uid */