blob: ff5f0292bc39aac720cf34a281ce74e47ea1943e [file] [log] [blame]
Dmitrii Sutiagind7d6e772017-08-18 13:23:15 -07001parameters:
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 }