Dmitrii Sutiagin | d7d6e77 | 2017-08-18 13:23:15 -0700 | [diff] [blame] | 1 | parameters: |
| 2 | linux: |
| 3 | system: |
| 4 | profile: |
| 5 | # script provides sudoon & sudooff commands, allows working as-if root while tracking all commands |
| 6 | autosudo.sh: | |
| 7 | #!/bin/bash |
| 8 | |
| 9 | # USAGE: $ . autosudo.sh |
| 10 | # $ sudoon |
| 11 | # $ sudo: <any commands> |
| 12 | # $ sudo: ... |
| 13 | # $ sudo: sudooff |
| 14 | # LIMITATIONS: |
| 15 | # - does not check your sudo policy, assumes "bash -c ..." is allowed |
| 16 | # - autocompletion (tab) for files/dirs does not work in restricted folders |
| 17 | # - may contain bugs |
| 18 | # NOTES: supports "cd ..."; allows to freely operate in restricted directories |
| 19 | |
| 20 | function sudoon () { |
| 21 | if [ -z "$PREEXEC_PROMPT" ] |
| 22 | then |
| 23 | trap - DEBUG |
| 24 | ORIGINAL_PROMPT_COMMAND="$PROMPT_COMMAND" |
| 25 | PREEXEC_PROMPT=1 |
| 26 | ORIGINAL_PS1=$PS1 |
| 27 | PS1=$ORIGINAL_PS1"sudo: " |
| 28 | shopt -s extdebug |
| 29 | PROMPT_COMMAND="_preexec_prompt" |
| 30 | trap "_preexec_sudo" DEBUG |
| 31 | fi |
| 32 | } |
| 33 | |
| 34 | function sudooff () { |
| 35 | trap - DEBUG |
| 36 | shopt -u extdebug |
| 37 | unset PREEXEC_PROMPT |
| 38 | PS1=$ORIGINAL_PS1 |
| 39 | unset SUDO_DIR |
| 40 | PROMPT_COMMAND="$ORIGINAL_PROMPT_COMMAND" |
| 41 | unset ORIGINAL_PROMPT_COMMAND |
| 42 | } |
| 43 | |
| 44 | function _preexec_prompt() { |
| 45 | trap - DEBUG |
| 46 | PREEXEC_PROMPT=1 |
| 47 | trap "_preexec_sudo" DEBUG |
| 48 | } |
| 49 | |
| 50 | |
| 51 | function _preexec_sudo() { |
| 52 | # echo PREEXEC_PROMPT=$PREEXEC_PROMPT BASH_COMMAND=$BASH_COMMAND SUDO_DIR=$SUDO_DIR |
| 53 | [ -n "$COMP_LINE" ] && return |
| 54 | [ "$BASH_COMMAND" == "$PROMPT_COMMAND" ] && return |
| 55 | [ -z "$BASH_COMMAND" ] && return |
| 56 | [[ "$BASH_COMMAND" =~ ^exit$|^set\ |^shopt\ |^trap\ |^sudoon$|^sudooff$ ]] && return |
| 57 | [ -z "$PREEXEC_PROMPT" ] && return |
| 58 | if [ "$PREEXEC_PROMPT" -eq 0 ]; then |
| 59 | # echo cancelling "$BASH_COMMAND" |
| 60 | return 1 |
| 61 | fi |
| 62 | |
| 63 | # echo "trap-DEBUG" |
| 64 | trap - DEBUG |
| 65 | PREEXEC_PROMPT=0 |
| 66 | FULL_COMMAND=$(HISTTIMEFORMAT='' history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//") |
| 67 | # echo "Running _preexec_sudo $FULL_COMMAND" |
| 68 | ARG_0=$(cut -d' ' -f1 <<< "$BASH_COMMAND") |
| 69 | TYPE=$(type "$ARG_0" 2> /dev/null | head -n 1) |
| 70 | if [[ ! "$TYPE" =~ / ]] |
| 71 | then |
| 72 | if [ "$BASH_COMMAND" == "$FULL_COMMAND" ] |
| 73 | then |
| 74 | if [[ "$BASH_COMMAND" =~ ^cd\ ]] |
| 75 | then |
| 76 | if [ -z "$SUDO_DIR" ] |
| 77 | then |
| 78 | if $BASH_COMMAND 2> /dev/null |
| 79 | then |
| 80 | trap "_preexec_sudo" DEBUG |
| 81 | return 1 |
| 82 | else |
| 83 | DIR=$(sudo bash -c "$BASH_COMMAND; pwd") |
| 84 | DIR_ERR=$? |
| 85 | fi |
| 86 | else |
| 87 | DIR=$(sudo bash -c "cd $SUDO_DIR; $BASH_COMMAND; pwd") |
| 88 | DIR_ERR=$? |
| 89 | fi |
| 90 | if [ "$DIR_ERR" -eq 0 ] |
| 91 | then |
| 92 | if cd "$DIR" 2> /dev/null |
| 93 | then |
| 94 | SUDO_DIR='' |
| 95 | PS1=$ORIGINAL_PS1"sudo: " |
| 96 | else |
| 97 | SUDO_DIR=$DIR |
| 98 | [ -n "$SUDO_DIR" ] && PS1_SUDO_DIR="($(echo "$SUDO_DIR" | rev | cut -d'/' -f1 | rev))" || PS1_SUDO_DIR='' |
| 99 | PS1=$ORIGINAL_PS1"sudo$PS1_SUDO_DIR: " |
| 100 | fi |
| 101 | fi |
| 102 | trap "_preexec_sudo" DEBUG |
| 103 | return 1 |
| 104 | elif [ -z "$SUDO_DIR" ] |
| 105 | then |
| 106 | trap "_preexec_sudo" DEBUG |
| 107 | return # single call to function / builtin; not sudoing |
| 108 | fi |
| 109 | fi |
| 110 | fi |
| 111 | [[ "$TYPE" =~ / ]] && [ "$(which "$ARG_0")" == "$(which sudo)" ] && return 0 # execute explicit sudo as-is |
| 112 | if [ -n "$SUDO_DIR" ] |
| 113 | then |
| 114 | CMD_DIR="cd $SUDO_DIR; " |
| 115 | else |
| 116 | CMD_DIR='' |
| 117 | fi |
| 118 | if [ ! "$BASH_COMMAND" == "$FULL_COMMAND" ] || [ -n "$CMD_DIR" ] |
| 119 | then |
| 120 | # echo combined or cd command: `printf '%q' "$CMD_DIR$FULL_COMMAND"` |
| 121 | eval sudo -E bash -c $(printf '%q' "$CMD_DIR$FULL_COMMAND") |
| 122 | else |
| 123 | eval sudo -E $FULL_COMMAND |
| 124 | fi |
| 125 | trap "_preexec_sudo" DEBUG |
| 126 | return 1 |
| 127 | } |