Last active
February 2, 2022 13:04
-
-
Save YuriyGuts/f1bd6d9981081b530e37bb1a915c5e83 to your computer and use it in GitHub Desktop.
Installs a PAM configuration script as a macOS launch daemon so that Touch ID for sudo is always available and persists across OS updates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# This script installs a PAM configuration script as a macOS launch daemon | |
# so that Touch ID for sudo is always available and persists across OS updates. | |
# NOTE: You might need to allow /usr/bin/env in Security & Privacy > Full Disk Access. | |
set -euo pipefail | |
PACKAGE_NAME="com.yuriyguts.persistent-touch-id-sudo" | |
CONFIG_SCRIPT_INSTALL_PATH="/usr/local/bin/${PACKAGE_NAME}.sh" | |
LAUNCH_DAEMON_INSTALL_PATH="/Library/LaunchDaemons/${PACKAGE_NAME}.plist" | |
function install_config_script { | |
tee "${CONFIG_SCRIPT_INSTALL_PATH}" > /dev/null <<EOT | |
#!/usr/bin/env bash | |
if ! grep 'pam_tid.so' /etc/pam.d/sudo --silent; then | |
sed -i -e '1s;^;auth sufficient pam_tid.so\n;' /etc/pam.d/sudo | |
fi | |
EOT | |
chmod +x "${CONFIG_SCRIPT_INSTALL_PATH}" | |
} | |
function install_launch_daemon { | |
tee "${LAUNCH_DAEMON_INSTALL_PATH}" > /dev/null <<EOT | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Label</key> | |
<string>${PACKAGE_NAME}</string> | |
<key>KeepAlive</key> | |
<false/> | |
<key>LaunchOnlyOnce</key> | |
<true/> | |
<key>RunAtLoad</key> | |
<true/> | |
<key>ProgramArguments</key> | |
<array> | |
<string>${CONFIG_SCRIPT_INSTALL_PATH}</string> | |
</array> | |
<key>StandardOutPath</key> | |
<string>/tmp/${PACKAGE_NAME}.stdout.log</string> | |
<key>StandardErrorPath</key> | |
<string>/tmp/${PACKAGE_NAME}.stderr.log</string> | |
</dict> | |
</plist> | |
EOT | |
launchctl load -w "${LAUNCH_DAEMON_INSTALL_PATH}" | |
} | |
function ensure_root { | |
if [[ $(id -u) -ne 0 ]]; then | |
echo "Error: this script needs to be run as root" | |
exit 1 | |
fi | |
} | |
function main { | |
ensure_root | |
echo "Installing the config script to ${CONFIG_SCRIPT_INSTALL_PATH}" | |
install_config_script | |
echo "Installing the launch daemon to ${LAUNCH_DAEMON_INSTALL_PATH}" | |
install_launch_daemon | |
echo "Done!" | |
} | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another somewhat related gist.