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