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