Skip to content

Instantly share code, notes, and snippets.

@bunam
Forked from juliyvchirkov/macos-sudo-nopasswd.sh
Created July 2, 2023 23:34
Show Gist options
  • Save bunam/a7ec1a8c58bd61e5c489dc8f5c0696cf to your computer and use it in GitHub Desktop.
Save bunam/a7ec1a8c58bd61e5c489dc8f5c0696cf to your computer and use it in GitHub Desktop.
bash: sudo without a password on macOS

Purpose

Enable nopasswd mode for sudo on macOS from the userspace in fast and totally non-interactive way

Type your sudo password one last time to enable nopasswd mode and forget it for any console task for ages

Warning

Althrough NOPASSWD doesn't have a major impact on security, it needs to be clarified and clearly stated that you are acting as a person aware of the possible consequences. Enabling NOPASSWD for sudo, no matter with or without this script, you realize the risks and on your own take the whole responsibility for any claims, damages or other liability, arising from, in connection with or out of access from your userspace to the sudo command without password protection on your macOS

Features

  • Enables nopasswd mode in 0.14769983291626 sec
  • Provides the rollback. Disables nopasswd mode in 0.097800025939941 sec
  • Implements silent autofixes for missing settings and environment
  • Includes various checks to avoid conflicts with existing configuration

Environment

Designed and tested with GNU bash 3.2.57(1)-release on macOS Big Sur 11.2.0 (Darwin Kernel Version 20.3.0 Thu Jan 21 00:07:06 PST 2021)

macOS SIP is disabled (since OS X El Capitan 10.11)

Depends on coreutils sudo, visudo, mkdir, rm, chmod, grep, cat, grep, wc, basename and hostname.

Setup routine also requires wget utility to retrieve the script from Github Gist

Warning

Most likely you will need to disable macOS System Integrity Protection before using this script (or applying any other changes to system files), otherwise active SIP won't let you to modify system files under /private/etc/ folder owned by root:wheel

Steps to disable SIP

  1. If your hard drive is encrypted, you have to decrypt it first and disable FileVault
  2. Boot into recovery mode, holding down and R keys while starting up your computer
  3. Launch Utilities > Terminal from the menu bar
  4. Run command csrutil authenticated-root disable; csrutil disable; reboot

To check current status of SIP, open Terminal.app and run csrutil authenticated-root status; csrutil status. When nopasswd mode for sudo will be enabled, you can turn SIP back on

Steps to enable SIP

  1. Boot into recovery mode, holding down and R keys while starting up your computer
  2. Launch Utilities > Terminal from the menu bar
  3. Run command csrutil authenticated-root enable; csrutil enable; reboot

Usage

To enable nopasswd mode

  1. Open Terminal.app
  2. Copy the following command, paste it to command line and launch
  3. Type your sudo password one last time to let the script to process
  4. Enjoy!
cd ${HOME}; \
wget https://gist.githubusercontent.com/juliyvchirkov/3ca76582ed6b6a8366c9e7d60644960d/raw/macos-sudo-nopasswd.sh -O macos-sudo-nopasswd.sh; \
chmod 755 macos-sudo-nopasswd.sh; \
./macos-sudo-nopasswd.sh

Since the goal is now achieved, you can safely remove downloaded script. Delete it with rm macos-sudo-nopasswd.sh command in Terminal.app or drop to Trash from the Finder.app

To disable nopasswd mode

  1. Open Terminal.app
  2. Copy the following command, paste it to command line and launch
  3. That's all! Due to nopasswd mode the rollback is completely non-interactive, and from now on your sudo will require the password again
cd ${HOME}; \
wget https://gist.githubusercontent.com/juliyvchirkov/3ca76582ed6b6a8366c9e7d60644960d/raw/macos-sudo-nopasswd.sh -O macos-sudo-nopasswd.sh; \
chmod 755 macos-sudo-nopasswd.sh; \
./macos-sudo-nopasswd.sh --undo

Since the goal is now achieved, you can safely remove downloaded script. Delete it with rm macos-sudo-nopasswd.sh command in Terminal.app or drop to Trash from the Finder.app

To re-enable and re-disable nopasswd mode at any moment repeat the steps from the appropriative above block

Troubleshooting

Warning

Improper use of sudo command can lead to data loss or the deletion of important system files. Always double-check your typing when using sudo. Type man sudo in Terminal.app for more information

System sudoers config is stored in /private/etc/sudoers, custom sudoers profiles can be found under /private/etc/sudoers.d folder

Sudoers directives are declared as plain text. Use Terminal.app to inspect sudoers configuration in case of some emergency with sudo settings

  • Investigate the routine in details
man sudo
man sudoers
man visudo
  • Check sudoers config files for syntax errors and invalid permissions
sudo visudo -c
  • Review the list of custom sudoers profiles
sudo ls -lAh /private/etc/sudoers.d
  • Try to force correct permissions for custom sudoers profiles
sudo chmod 440 /private/etc/sudoers.d/*
  • Inspect directives in all custom sudoers profiles at once in sequence
sudo bash -c \
"for conf in /private/etc/sudoers.d/*; \
do echo -e \"> \${conf} \n\"; cat \${conf}; done |
less -F"
  • Inspect directives in system sudoers config the same way
sudo less /private/etc/sudoers -F
  • This script on the first run just in case backups system sudoers config at /private/etc/sudoers.default. Try to compare that saved edition with the current one
sudo diff /private/etc/sudoers /private/etc/sudoers.default
  • Temporary remove all custom sudoers profiles and see if it helps
sudo bash -c \
"mkdir /private/tmp/sudoers.d; \
mv /private/etc/sudoers.d/* /private/tmp/sudoers.d/; \
visudo -c"

#. If the move solves the problem, try to return custom sudoers profiles back one by one with dedicated step on each one. Check for the problem again after each step

sudo bash -c \
"find /private/tmp/sudoers.d -type f -print0 -quit |
xargs -0 -I{} mv -v {} /private/etc/sudoers.d/; \
chmod 440 /private/etc/sudoers.d/*; \
visudo -c"

Credits

Implemented by @juliyvchirkov under the MIT license

#!/bin/bash
#
# Enable nopasswd mode for sudo on macOS from the userspace in fast and totally non-interactive way
#
# Type the password last time to apply the new mode and forget it for any console task for ages
# Use the rollback to restore password protection
#
# Developed and tested by https://juliyvchirkov.github.io/ under the MIT license on macOS Big Sur 11.2.0
#
# Get latest version at https://gist.github.com/juliyvchirkov/3ca76582ed6b6a8366c9e7d60644960d
#
# See https://gist.github.com/juliyvchirkov/3ca76582ed6b6a8366c9e7d60644960d#file-readme-rst for details
if [[ ${USER} != root ]]
then
/usr/bin/sudo /bin/bash ${0} ${1}
else
sudoers=/private/etc/sudoers
sudoersd=${sudoers}.d
sudoersinc="#includedir ${sudoersd}"
whoami=${SUDO_USER}
usersudoersd=${sudoersd}/${whoami}-nopasswd
hostname=$(/bin/hostname -s)
if [[ "${1}" = "--undo" ]]
then
if [ -f ${usersudoersd} ]
then
/bin/rm -f ${usersudoersd}
/usr/sbin/visudo -cq
echo -e "sudo in nopasswd mode has been disabled for ${whoami}@${hostname}"
else
echo -e "Sorry, seems this script hasn't been used to enable nopasswd mode for ${whoami}@${hostname}, or it has been already disabled.\nTry to inspect the content of ${sudoersd} folder manually"
fi
else
[ -d ${sudoersd} ] || /bin/mkdir -m755 ${sudoersd}
if [ -f ${usersudoersd} ]
then
echo -e "Sorry, seems this script has already been used to enable nopasswd mode for ${whoami}@${hostname}\nTo rollback changes run this script once again with --undo option\n\n\t$(/usr/bin/basename ${0}) --undo\n"
else
echo "${whoami} ALL=(ALL:ALL) NOPASSWD: ALL" >${usersudoersd}
/bin/chmod 440 ${usersudoersd}
[ -f ${sudoers}.default ] || cp -a ${sudoers} ${sudoers}.default
/usr/bin/grep "${sudoersinc}" ${sudoers} >/dev/null || echo -e "\n${sudoersinc}" >>${sudoers}
/usr/sbin/visudo -cq
echo -e "Congrats, ${whoami}@${hostname}! nopasswd mode for sudo has been enabled\nTo rollback changes run this script once again with --undo option\n\n\t$(/usr/bin/basename ${0}) --undo\n"
fi
[ $(cat ${sudoers} ${sudoersd}/* | /usr/bin/grep ${whoami} | /usr/bin/wc -l) -ne 1 ] && echo -e "\n*WARNING* Another mention of ${whoami}@${hostname} has been found at sudoers config files!\nTry to inspect the content of sudoers system config and custom profiles to alter settings manually and avoid possible conflicts\nSystem config: ${sudoers}\nCustom profiles: ${sudoersd}/"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment