Most of the logic

This commit is contained in:
Salt 2024-12-01 22:08:27 -06:00
parent 0210515b8c
commit 9971b7f33a

View File

@ -1,4 +1,4 @@
#! /bin/sh
#! /bin/bash
#
# This script attempts to fix the following issue:
# https://github.com/wayblueorg/wayblue/issues/89
@ -41,4 +41,55 @@ for file in /etc/shadow /etc/gshadow; do
fi
# Prelim checks succeeded, move forward
echo "Parsing $file for junk"
# Read each line in the file to iterate over it
while read line; do
# Per shadow(5), we are guaranteed that all characters leading up to the
# first colon are the user's/group's name. To that end, we'll do a bash
# string substitution to extract that first column.
name="${line%%:*}"
# Swith case here for what ents we care about. I don't think the array is
# strictly required but it affords us flexibility for zero cost so whatever.
ents=()
case "$file" in
/etc/shadow)
ents=("passwd")
;;
/etc/gshadow)
ents=("group")
;;
*)
echo "Unknown file to parse for junk: $file"
exit
;;
esac
# Now, we use getent to find a match for the shadow entry. It's at this point
# that one might ask why we're doing this instead of using grpck or something
# The answer is that those aren't nss-aware, whereas getent is. /etc/shadow
# and /etc/gshadow can have entries for things like passwords and group
# membership for groups that live in /usr/lib/passwd and /usr/lib/group,
# but grpck isn't aware of those and will obliterate their data from the
# shadow files if we're not careful.
#
# Thus, we use getent to parse through nsswitch.conf intelligently and tell
# us whether this object we're operating on is found elsewhere in the OS
matched_ent=""
for ent in "${ents[@]}"; do
[ -n "$matched_ent" ] && break
# We have to do || true here because getent exits nonzero if it fails to
# find an entity. We need to store its output so we can analyze the status
# of this command outside the loop -- we can't just "if ! getent"
result="$(getent "$ent" "$name" || true)"
[ -n "$result" ] && matched_ent="$result"
done
if [ -n "$matched_ent" ]; then
# getent found a matching entity and we don't care about this entry
# Just continue down the line
continue
else
# If we're at this point in the code path, we now know that we for-sure are
# operating on an entry that will cause systemd-sysusers to bail out
# on invocation
echo "Fixing broken entity: $name"
fi
done < "$file"
done