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