From: Dan Nicholson Date: Tue, 30 Jul 2024 19:42:26 +0000 (-0600) Subject: firstboot: handle missing root password entries X-Git-Tag: v257-rc1~773^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2319154a6bec7b8c42e901dfacaefe95bf4e3750;p=thirdparty%2Fsystemd.git firstboot: handle missing root password entries If /etc/passwd and/or /etc/shadow exist but don't have an existing root entry, one needs to be added. Previously this only worked if the files didn't exist. --- diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index acbe3e29b68..b6512b05a4d 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -908,6 +908,7 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch _cleanup_fclose_ FILE *original = NULL, *passwd = NULL; _cleanup_(unlink_and_freep) char *passwd_tmp = NULL; int r; + bool found = false; assert(password); @@ -932,6 +933,7 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch i->pw_passwd = (char *) password; if (shell) i->pw_shell = (char *) shell; + found = true; } r = putpwent_sane(i, passwd); @@ -942,6 +944,12 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch return r; } else { + r = fchmod(fileno(passwd), 0644); + if (r < 0) + return -errno; + } + + if (!found) { struct passwd root = { .pw_name = (char *) "root", .pw_passwd = (char *) password, @@ -955,10 +963,6 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch if (errno != ENOENT) return -errno; - r = fchmod(fileno(passwd), 0644); - if (r < 0) - return -errno; - r = putpwent_sane(&root, passwd); if (r < 0) return r; @@ -979,6 +983,7 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) { _cleanup_fclose_ FILE *original = NULL, *shadow = NULL; _cleanup_(unlink_and_freep) char *shadow_tmp = NULL; int r; + bool found = false; assert(hashed_password); @@ -1002,6 +1007,7 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) { if (streq(i->sp_namp, "root")) { i->sp_pwdp = (char *) hashed_password; i->sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY); + found = true; } r = putspent_sane(i, shadow); @@ -1012,6 +1018,12 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) { return r; } else { + r = fchmod(fileno(shadow), 0000); + if (r < 0) + return -errno; + } + + if (!found) { struct spwd root = { .sp_namp = (char*) "root", .sp_pwdp = (char *) hashed_password, @@ -1027,10 +1039,6 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) { if (errno != ENOENT) return -errno; - r = fchmod(fileno(shadow), 0000); - if (r < 0) - return -errno; - r = putspent_sane(&root, shadow); if (r < 0) return r; diff --git a/test/units/TEST-74-AUX-UTILS.firstboot.sh b/test/units/TEST-74-AUX-UTILS.firstboot.sh index 48792c4c676..7617b01bca7 100755 --- a/test/units/TEST-74-AUX-UTILS.firstboot.sh +++ b/test/units/TEST-74-AUX-UTILS.firstboot.sh @@ -91,6 +91,13 @@ systemd-firstboot --root="$ROOT" --root-password-file=root.passwd grep -q "^root:x:0:0:" "$ROOT/etc/passwd" grep -q "^root:[^!*]" "$ROOT/etc/shadow" rm -fv "$ROOT/etc/passwd" "$ROOT/etc/shadow" root.passwd +# Make sure the root password is set if /etc/passwd and /etc/shadow exist but +# don't have a root entry. +touch "$ROOT/etc/passwd" "$ROOT/etc/shadow" +systemd-firstboot --root="$ROOT" --root-password=foo +grep -q "^root:x:0:0:" "$ROOT/etc/passwd" +grep -q "^root:[^!*]" "$ROOT/etc/shadow" +rm -fv "$ROOT/etc/passwd" "$ROOT/etc/shadow" # If /etc/passwd and /etc/shadow exist, they will only be updated if the shadow # password is !unprovisioned. echo "root:x:0:0:root:/root:/bin/sh" >"$ROOT/etc/passwd"