From ad658ee76f7892ece90333c64a7f0877f30afbfe Mon Sep 17 00:00:00 2001 From: Kai Lueke Date: Tue, 17 Jan 2023 14:59:37 +0100 Subject: [PATCH] flatcar-tmpfiles: Always copy missing entries over to the database When a user or group entry is missing but the passwd/group file exists it is not added by flatcar-tmpfiles and systemd-tmpfiles will then fail because it can't resolve the user or group. We only care about the fixed set of users like "core" because those are the ones that the user will normally customize and this is also enough to fix the bug because tmpfiles.d/baselayout-home.conf is the only place where not "root" is used but another user which is "core". Always copy the missing entries (from the fixed list of entries to be copied) over to the database under /etc/, regardless if it exists or not. --- scripts/flatcar-tmpfiles | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/scripts/flatcar-tmpfiles b/scripts/flatcar-tmpfiles index 9b9e1d4..824bfdb 100644 --- a/scripts/flatcar-tmpfiles +++ b/scripts/flatcar-tmpfiles @@ -16,18 +16,23 @@ mkdir -p "${ROOT}/etc" # readable files umask 022 -if [[ ! -e "${ROOT}/etc/passwd" ]]; then - grep -E -e "^(${COPY_USERS}):" "${BASE}/passwd" > "${ROOT}/etc/passwd" -fi -if [[ ! -e "${ROOT}/etc/group" ]]; then - grep -E -e "^(${COPY_GROUPS}):" "${BASE}/group" > "${ROOT}/etc/group" -fi +# Output those lines in BASE/passwd (that are to be copied) when their user/group names are not in /etc/passwd already, +# and append the entries from BASE/passwd to /etc/passwd. +# But since we don't want lines/half lines being added also be used as patterns, we copy the file first to memory by +# storing it in the PATTERNS variable. +# (if it doesn't exist we are fine with empty output as patterns which means to match empty lines which inverted is all). +PATTERNS=$(cut -s -d ":" -f 1 "${ROOT}/etc/passwd" | sed 's/^/\^/' | sed 's/$/:.*$/') +grep -v -x -f <(echo "${PATTERNS}") <(grep -E -e "^(${COPY_USERS}):" "${BASE}/passwd") >> "${ROOT}/etc/passwd" +PATTERNS=$(cut -s -d ":" -f 1 "${ROOT}/etc/group" | sed 's/^/\^/' | sed 's/$/:.*$/') +grep -v -x -f <(echo "${PATTERNS}") <(grep -E -e "^(${COPY_GROUPS}):" "${BASE}/group") >> "${ROOT}/etc/group" # secure files umask 027 -if [[ ! -e "${ROOT}/etc/shadow" ]]; then - grep -E -e "^(${COPY_USERS}):" "${BASE}/shadow" > "${ROOT}/etc/shadow" -fi -if [[ ! -e "${ROOT}/etc/gshadow" ]]; then - grep -E -e "^(${COPY_GROUPS}):" "${BASE}/gshadow" > "${ROOT}/etc/gshadow" -fi +PATTERNS=$(cut -s -d ":" -f 1 "${ROOT}/etc/shadow" | sed 's/^/\^/' | sed 's/$/:.*$/') +grep -v -x -f <(echo "${PATTERNS}") <(grep -E -e "^(${COPY_USERS}):" "${BASE}/shadow") >> "${ROOT}/etc/shadow" +PATTERNS=$(cut -s -d ":" -f 1 "${ROOT}/etc/gshadow" | sed 's/^/\^/' | sed 's/$/:.*$/') +grep -v -x -f <(echo "${PATTERNS}") <(grep -E -e "^(${COPY_GROUPS}):" "${BASE}/gshadow") >> "${ROOT}/etc/gshadow" + +# The script runs without set -euo pipefail and allows grep to return 1, thus the last statement must not be grep +# because it would propagate the exit code 1 and let the systemd unit fail. +exit 0