Skip to content

Instantly share code, notes, and snippets.

@cowboy
Last active December 24, 2015 02:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save cowboy/6733297 to your computer and use it in GitHub Desktop.
Save cowboy/6733297 to your computer and use it in GitHub Desktop.
bash: sudo hack to work around the huge install script I use, where an installer does sudo -k halfway through :/
#!/usr/bin/env bash
# sudo enable-disable hack
#
# Copyright (c) 2013 "Cowboy" Ben Alman
# Licensed under the MIT license.
# http://benalman.com/about/license/
if [[ "$UID" == "0" ]]; then
echo 'Error: Do not run this script as root or using sudo.'
exit 1
fi
sudo_pipe=
sudo_rnd=$(python -c 'import os;print "-".join(str(ord(x)) for x in os.urandom(9))')
sudo_already=0; [[ ! "$(sudo -n test 2>&1)" ]] && sudo_already=1
function sudo() {
if [[ ! "$sudo_pipe" ]]; then
sudo_pipe=$(mktemp -d /tmp/sudo.XXXXXX)/pipe
mkfifo $sudo_pipe
local fns="$(declare -f sudo_enable sudo_disable sudo_quit sudo_daemon)"
command sudo bash -c "$fns; sudo_daemon $$ $sudo_rnd $sudo_pipe $sudo_already $USER $(tty)"
fi
sudo_enable
command sudo "$*"
sudo_disable
}
function sudo_enable() { echo "$sudo_rnd-enable" > $sudo_pipe; }
function sudo_disable() { echo "$sudo_rnd-disable" > $sudo_pipe; }
function sudo_quit() { echo "$sudo_rnd-quit" > $sudo_pipe; }
function sudo_daemon() {
[[ ! "$5" ]] && echo 'Error: no $USER environment variable?' && exit 1
local parent_pid=$1
local sudo_rnd="$2"
local sudo_pipe=$3
local sudo_already=$4
local sudo_file sudo_dir d tty
# Yes, I looked at the sudo source code.
for d in /var/db /var/lib /var/adm /usr/adm; do
[[ -d "$d" ]] && sudo_dir="$d/sudo/$5" && break
done
[[ ! "$sudo_dir" ]] && echo 'Error: sudo timestamp directory not found.' && exit 1
sudo_file="$sudo_dir"
# This might only apply to Ubuntu 12.04, dunno about other OSes.
tty="${6##/dev/pts/}"; [[ -e "$sudo_dir/$tty" ]] && sudo_file="$sudo_dir/$tty"
# Read commands from the pipe.
while read cmd; do
echo "??? $cmd"
# Refresh sudo timestamp.
if [[ "$cmd" == "$sudo_rnd-enable" ]]; then
[[ ! -d "$sudo_dir" ]] && mkdir "$sudo_dir"
touch "$sudo_file"
# Remove sudo timestamp.
elif [[ "$cmd" == "$sudo_rnd-disable" ]]; then
touch -t 196912310000 "$sudo_file"
# Quit.
elif [[ "$cmd" == "$sudo_rnd-quit" ]]; then
[[ $sudo_already == 1 ]] && touch "$sudo_file"
break
fi
done <>$sudo_pipe >/dev/null 2>&1 &
# Kill daemon when parent script exits, otherwise refresh sudo timestamp.
while true; do
sleep 1
if kill -0 "$parent_pid"; then sudo_enable; else sudo_quit; break; fi
done >/dev/null 2>&1 &
}
echo -e '>>> Running "sudo date" (should prompt ONLY if sudo timestamp was not already set)'
sudo date
echo -e '\n>>> Running command that does sudo -k for safety'
# brew install cowsay
sudo -k
echo -e '\n>>> Running "sudo date" (should not prompt)'
sudo date
echo -e '\n>>> Running command that uses sudo internally (should prompt)'
./sudo-test-internal-sudo.sh
echo -e '\n>>> Running "sudo date" (should NOT prompt)'
sudo date
echo -e '\n>>> Running command that uses sudo internally (should NOT prompt)'
sudo_enable
./sudo-test-internal-sudo.sh
sudo_disable
echo -e '\n>>> Running command that uses sudo internally (should prompt)'
./sudo-test-internal-sudo.sh
echo -e '\n>>> Running "sudo date" (should NOT prompt)'
sudo date
echo -e '\n>>> Any sudo timestamp from before running this script should be restored'
#!/usr/bin/env bash
echo ">>> >>> starting $0"
sudo bash -c "echo '>>> >>>' this command is run via sudo"
echo ">>> >>> ending $0"
$ sudo -k
$ ./sudo-hack.sh
>>> Running "sudo date" (should prompt ONLY if sudo timestamp was not already set)
Password:
Fri Sep 27 14:41:53 EDT 2013
>>> Running command that does sudo -k for safety
>>> Running "sudo date" (should not prompt)
Fri Sep 27 14:41:54 EDT 2013
>>> Running command that uses sudo internally (should prompt)
>>> >>> starting ./sudo-test-internal-sudo.sh
Password:
>>> >>> this command is run via sudo
>>> >>> ending ./sudo-test-internal-sudo.sh
>>> Running "sudo date" (should NOT prompt)
Fri Sep 27 14:41:59 EDT 2013
>>> Running command that uses sudo internally (should NOT prompt)
>>> >>> starting ./sudo-test-internal-sudo.sh
>>> >>> this command is run via sudo
>>> >>> ending ./sudo-test-internal-sudo.sh
>>> Running command that uses sudo internally (should prompt)
>>> >>> starting ./sudo-test-internal-sudo.sh
Password:
>>> >>> this command is run via sudo
>>> >>> ending ./sudo-test-internal-sudo.sh
>>> Running "sudo date" (should NOT prompt)
Fri Sep 27 14:42:03 EDT 2013
>>> Note: sudo timestamp from before running this script should be restored
$ sudo date
Password:
@cowboy
Copy link
Author

cowboy commented Oct 22, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment