Add set-root-password command
The `set-root-password` command sets up an alternate mount namespace with a writable `/etc` directory and then runs `passwd` in it. This allows `passwd` to create its lock files and backup files, without requiring that the real `/etc` to be mutable. After `passwd` finishes and has updated its private copy of `/etc/shadow`, the script rewrites the real one with its contents.
This commit is contained in:
56
overlay/usr/bin/set-root-password
Executable file
56
overlay/usr/bin/set-root-password
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/sh
|
||||
# vim: set sw=4 ts=4 sts=4 et :
|
||||
|
||||
if [ -z "${_UNSHARED}" ]; then
|
||||
export _UNSHARED=1
|
||||
exec unshare -m "$0" "$@"
|
||||
fi
|
||||
unset _UNSHARED
|
||||
|
||||
cleanup() {
|
||||
if is_mount -q /etc; then
|
||||
umount -R /etc
|
||||
fi
|
||||
if [ -n "${tmpdir}" ] && [ "${tmpdir}" != / ]; then
|
||||
if is_mount "${tmpdir}"; then
|
||||
umount -R "${tmpdir}"
|
||||
fi
|
||||
rm -rf "${tmpdir}"
|
||||
fi
|
||||
unset tmpdir
|
||||
}
|
||||
|
||||
is_mount() {
|
||||
awk '
|
||||
BEGIN { rc = 1 }
|
||||
$5 == "'"${1}"'" { rc = 0 }
|
||||
END { exit rc }
|
||||
' /proc/self/mountinfo
|
||||
}
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
trap 'cleanup' INT QUIT TERM EXIT
|
||||
mount \
|
||||
-t tmpfs \
|
||||
-o private,rootcontext=system_u:object_r:etc_t:s0 \
|
||||
tmpfs \
|
||||
"${tmpdir}" \
|
||||
|| exit
|
||||
|
||||
mkdir -p \
|
||||
"${tmpdir}"/etc \
|
||||
"${tmpdir}"/etc/pam.d \
|
||||
"${tmpdir}"/etc/security \
|
||||
"${tmpdir}"/etc/selinux \
|
||||
|| exit
|
||||
cp -a /etc/passwd /etc/shadow "${tmpdir}"/etc || exit
|
||||
mount -o bind /etc/pam.d "${tmpdir}"/etc/pam.d || exit
|
||||
mount -o bind /etc/security "${tmpdir}"/etc/security || exit
|
||||
mount -o bind /etc/selinux "${tmpdir}"/etc/selinux || exit
|
||||
mount --rbind "${tmpdir}"/etc /etc || exit
|
||||
|
||||
passwd || exit
|
||||
|
||||
mv /etc/shadow "${tmpdir}"/shadow || exit
|
||||
umount -R /etc || exit
|
||||
cat "${tmpdir}"/shadow > /etc/shadow || exit
|
||||
Reference in New Issue
Block a user