Skip to content

Commit

Permalink
feat: allow rescue/emergency boot with grub cmdline args (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsherman authored Feb 6, 2024
1 parent 578a260 commit c2ad2bf
Showing 1 changed file with 65 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/bash

# This systemd.generator(7) detects if rescue or emergency targets were
# requested from the kernel cmdline; if so, it overrides the respective
# target to set force sulogin, allowing use of rescue/emergency targets
# on systems with locked root password (as is Fedora default).
#
# This does NOT bypass locked root password on a fsck failure, but WILL
# bypass when rescue/emergency targets are chosen from kernel cmdline.
# Since this requires console/grub access, it is assumed to be at least
# as secure as a user reset of the root password using grub to modify
# the kernel cmdline with init=/bin/bash .
#
# NOTE: the SYSTEMD_SULOGIN_FORCE method used here does not bypass any
# assigned password; root password is only bypassed when locked/unset.

export PATH="/usr/bin:/usr/sbin:${PATH}"
if [ -n "$1" ]; then
# If invoked with arguments (not testing) log to kmsg
# https://github.com/systemd/systemd/issues/15638
exec 1>/dev/kmsg; exec 2>&1
fi

# If invoked with no arguments (for testing) write to /tmp
UNIT_DIR="${1:-/tmp}"

set -euo pipefail

have_some_karg() {
local args=("$@")
IFS=" " read -r -a cmdline <<< "$(</proc/cmdline)"
local i
for i in "${cmdline[@]}"; do
for a in "${args[@]}"; do
if [[ "$i" == "$a" ]]; then
return 0
fi
done
done
return 1
}

write_dropin() {
local service="$1"

local out_dir="${UNIT_DIR}/${service}.service.d"
mkdir -p "${out_dir}"

# /tmp isn't r/w yet, and the shell needs to cache the here-document
TMPDIR=/run
cat > "${out_dir}/sulogin-force.conf" <<EOF
[Service]
Environment=SYSTEMD_SULOGIN_FORCE=1
EOF
echo "$(basename ${0}): set SYSTEMD_SULOGIN_FORCE=1 for ${service}.service"
}

# Match kernel command line targets for systemd(1) rescue/emergency
# Ignores 'rd.' prefixed targets since they enter the dracut ramdisk
# environment which does not interact with installed system root user.
if have_some_karg 'systemd.unit=rescue.target' rescue single s S 1; then
write_dropin rescue
elif have_some_karg 'systemd.unit=emergency.target' emergency '-b' ; then
write_dropin emergency
fi

0 comments on commit c2ad2bf

Please sign in to comment.