1if [ ! "$_MUSTBEROOT_SUBR" ]; then _MUSTBEROOT_SUBR=1 2# 3# Copyright (c) 2006-2013 Devin Teske 4# All Rights Reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26#
| 1if [ ! "$_MUSTBEROOT_SUBR" ]; then _MUSTBEROOT_SUBR=1 2# 3# Copyright (c) 2006-2013 Devin Teske 4# All Rights Reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26#
|
27# $FreeBSD: head/usr.sbin/bsdconfig/share/mustberoot.subr 251190 2013-05-31 19:07:17Z dteske $
| 27# $FreeBSD: head/usr.sbin/bsdconfig/share/mustberoot.subr 251236 2013-06-01 23:58:44Z dteske $
|
28# 29############################################################ INCLUDES 30 31BSDCFG_SHARE="/usr/share/bsdconfig" 32. $BSDCFG_SHARE/common.subr || exit 1 33f_dprintf "%s: loading includes..." mustberoot.subr 34f_include $BSDCFG_SHARE/dialog.subr 35 36BSDCFG_LIBE="/usr/libexec/bsdconfig" 37f_include_lang $BSDCFG_LIBE/include/messages.subr 38 39############################################################ CONFIGURATION 40# NOTE: These are not able to be overridden/inherited for security purposes. 41 42# 43# Number of tries a user gets to enter his/her password before we log the 44# sudo(8) failure and exit. 45# 46PASSWD_TRIES=3 47 48# 49# While in SECURE mode, should authentication as `root' be allowed? Set to 50# non-NULL to enable authentication as `root', otherwise disabled. 51# 52# WARNING: 53# Unless using a custom sudo(8) configuration, user `root' should not be 54# allowed because no password is required to become `root' when already `root' 55# and therefore, any value entered as password will work. 56# 57SECURE_ALLOW_ROOT= 58 59# 60# While in SECURE mode, should we divulge (through error message) when the 61# requested authentication user does not exist? Set to non-NULL to enable, 62# otherwise a non-existent user is treated like an invalid password. 63# 64SECURE_DIVULGE_UNKNOWN_USER= 65 66############################################################ FUNCTIONS 67 68# f_become_root_via_sudo 69# 70# If not running as root, prompt for sudo(8) credentials to become root. 71# Re-execution of the current program via sudo is automatically handled. 72# 73# The following environment variables effect functionality: 74# 75# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate 76# that Xdialog(1) should be used instead of dialog(1). 77# 78f_become_root_via_sudo() 79{ 80 local msg hline height width rows 81 82 [ "$( id -u )" = "0" ] && return $SUCCESS 83 84 f_have sudo || f_die 1 "$msg_must_be_root_to_execute" "$pgm" 85 86 # 87 # Ask the user if it's OK to become root via sudo(8) and give them 88 # the option to save this preference (by touch(1)ing a file in the 89 # user's $HOME directory). 90 # 91 local checkpath="${HOME%/}/.bsdconfig_uses_sudo" 92 if [ ! -e "$checkpath" ]; then 93 msg=$( printf "$msg_always_try_sudo_when_run_as" "$USER" ) 94 local menu_list=" 95 'X' '$msg_cancel_exit' 96 '1' '$msg' 97 '2' '$msg_try_sudo_only_this_once' 98 " # END-QUOTE 99 msg=$( printf "$msg_you_are_not_root_but" bsdconfig ) 100 hline="$hline_arrows_tab_enter" 101 eval f_dialog_menu_size height width rows \ 102 \"\$DIALOG_TITLE\" \ 103 \"\$DIALOG_BACKTITLE\" \ 104 \"\$msg\" \ 105 \"\$hline\" \ 106 $menu_list 107
| 28# 29############################################################ INCLUDES 30 31BSDCFG_SHARE="/usr/share/bsdconfig" 32. $BSDCFG_SHARE/common.subr || exit 1 33f_dprintf "%s: loading includes..." mustberoot.subr 34f_include $BSDCFG_SHARE/dialog.subr 35 36BSDCFG_LIBE="/usr/libexec/bsdconfig" 37f_include_lang $BSDCFG_LIBE/include/messages.subr 38 39############################################################ CONFIGURATION 40# NOTE: These are not able to be overridden/inherited for security purposes. 41 42# 43# Number of tries a user gets to enter his/her password before we log the 44# sudo(8) failure and exit. 45# 46PASSWD_TRIES=3 47 48# 49# While in SECURE mode, should authentication as `root' be allowed? Set to 50# non-NULL to enable authentication as `root', otherwise disabled. 51# 52# WARNING: 53# Unless using a custom sudo(8) configuration, user `root' should not be 54# allowed because no password is required to become `root' when already `root' 55# and therefore, any value entered as password will work. 56# 57SECURE_ALLOW_ROOT= 58 59# 60# While in SECURE mode, should we divulge (through error message) when the 61# requested authentication user does not exist? Set to non-NULL to enable, 62# otherwise a non-existent user is treated like an invalid password. 63# 64SECURE_DIVULGE_UNKNOWN_USER= 65 66############################################################ FUNCTIONS 67 68# f_become_root_via_sudo 69# 70# If not running as root, prompt for sudo(8) credentials to become root. 71# Re-execution of the current program via sudo is automatically handled. 72# 73# The following environment variables effect functionality: 74# 75# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate 76# that Xdialog(1) should be used instead of dialog(1). 77# 78f_become_root_via_sudo() 79{ 80 local msg hline height width rows 81 82 [ "$( id -u )" = "0" ] && return $SUCCESS 83 84 f_have sudo || f_die 1 "$msg_must_be_root_to_execute" "$pgm" 85 86 # 87 # Ask the user if it's OK to become root via sudo(8) and give them 88 # the option to save this preference (by touch(1)ing a file in the 89 # user's $HOME directory). 90 # 91 local checkpath="${HOME%/}/.bsdconfig_uses_sudo" 92 if [ ! -e "$checkpath" ]; then 93 msg=$( printf "$msg_always_try_sudo_when_run_as" "$USER" ) 94 local menu_list=" 95 'X' '$msg_cancel_exit' 96 '1' '$msg' 97 '2' '$msg_try_sudo_only_this_once' 98 " # END-QUOTE 99 msg=$( printf "$msg_you_are_not_root_but" bsdconfig ) 100 hline="$hline_arrows_tab_enter" 101 eval f_dialog_menu_size height width rows \ 102 \"\$DIALOG_TITLE\" \ 103 \"\$DIALOG_BACKTITLE\" \ 104 \"\$msg\" \ 105 \"\$hline\" \ 106 $menu_list 107
|
108 local dialog_menu mtag retval 109 dialog_menu=$( eval $DIALOG \
| 108 local mtag 109 mtag=$( eval $DIALOG \
|
110 --title \"\$DIALOG_TITLE\" \ 111 --backtitle \"\$DIALOG_BACKTITLE\" \ 112 --hline \"\$hline\" \ 113 --ok-label \"\$msg_ok\" \ 114 --cancel-label \"\$msg_cancel\" \ 115 --menu \"\$msg\" \ 116 $height $width $rows \ 117 $menu_list \ 118 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
| 110 --title \"\$DIALOG_TITLE\" \ 111 --backtitle \"\$DIALOG_BACKTITLE\" \ 112 --hline \"\$hline\" \ 113 --ok-label \"\$msg_ok\" \ 114 --cancel-label \"\$msg_cancel\" \ 115 --menu \"\$msg\" \ 116 $height $width $rows \ 117 $menu_list \ 118 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
|
119 ) 120 retval=$? 121 setvar DIALOG_MENU_$$ "$dialog_menu" 122 mtag=$( f_dialog_menutag )
| 119 ) || f_die 120 f_dialog_data_sanitize mtag
|
123
| 121
|
124 [ $retval -eq 0 ] || f_die 125
| |
126 case "$mtag" in 127 X) # Cancel/Exit 128 f_die ;; 129 1) # Always try sudo(8) when run as $user 130 local err 131 if ! err=$( touch "$checkpath" 2>&1 ); then 132 f_dialog_msgbox "$err" 133 else 134 f_show_msg "$msg_created_path" "$checkpath" 135 fi 136 esac 137 else 138 # 139 # This user has created the path signing-off on sudo(8)-use 140 # but let's still give them a short/quick/unobtrusive reminder 141 # 142 f_dialog_info "$msg_becoming_root_via_sudo" 143 [ "$USE_XDIALOG" ] || sleep 0.6 144 fi 145 146 # 147 # Check sudo(8) access before prompting for password. 148 # 149 :| sudo -S -v 2> /dev/null 150 if [ $? -ne $SUCCESS ]; then 151 # 152 # sudo(8) access denied. Prompt for their password. 153 # 154 msg="$msg_please_enter_password" 155 hline="$hline_alnum_punc_tab_enter" 156 f_dialog_inputbox_size height width \ 157 "$DIALOG_TITLE" \ 158 "$DIALOG_BACKTITLE" \ 159 "$msg" \ 160 "$hline" 161 162 # 163 # Continue prompting until they either Cancel, succeed 164 # or exceed the number of allowed failures. 165 # 166 local password nfailures=0 retval 167 while [ $nfailures -lt $PASSWD_TRIES ]; do 168 if [ "$USE_XDIALOG" ]; then 169 password=$( $DIALOG \ 170 --title "$DIALOG_TITLE" \ 171 --backtitle "$DIALOG_BACKTITLE" \ 172 --hline "$hline" \ 173 --ok-label "$msg_ok" \ 174 --cancel-label "$msg_cancel" \ 175 --password --inputbox "$msg" \ 176 $height $width \ 177 2>&1 > /dev/null ) 178 retval=$? 179 180 # Catch X11-related errors 181 [ $retval -eq 255 ] && 182 f_die $retval "$password" 183 else 184 local dialog_inputbox 185 dialog_inputbox=$( $DIALOG \ 186 --title "$DIALOG_TITLE" \ 187 --backtitle "$DIALOG_BACKTITLE" \ 188 --hline "$hline" \ 189 --ok-label "$msg_ok" \ 190 --cancel-label "$msg_cancel" \ 191 --insecure \ 192 --passwordbox "$msg" \ 193 $height $width \ 194 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 195 ) 196 retval=$? 197 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 198 password=$( f_dialog_inputstr ) 199 fi 200 201 # Exit if the user cancelled. 202 [ $retval -eq $SUCCESS ] || exit $retval 203 204 # 205 # Validate sudo(8) credentials 206 # 207 sudo -S -v 2> /dev/null <<-EOF 208 $password 209 EOF 210 retval=$? 211 unset password # scrub memory 212 if [ $retval -eq $SUCCESS ]; then 213 # Access granted... 214 break 215 else 216 # Access denied... 217 nfailures=$(( $nfailures + 1 )) 218 219 # introduce a short delay 220 if [ $nfailures -lt $PASSWD_TRIES ]; then 221 f_dialog_info "$msg_sorry_try_again" 222 sleep 1 223 fi 224 fi 225 done 226 227 # 228 # If user exhausted number of allowed password tries, log 229 # the security event and exit immediately. 230 # 231 if [ $nfailures -ge $PASSWD_TRIES ]; then 232 msg=$( printf "$msg_nfailed_attempts" "$nfailures" ) 233 logger -p auth.notice -t sudo " " \ 234 "$USER : $msg" \ 235 "; TTY=$(tty)" \ 236 "; PWD=$PWD" \ 237 "; USER=root" \ 238 "; COMMAND=$0" 239 f_die 1 "sudo: $msg" 240 fi 241 fi 242 243 # Use xauth(1) to grant root the ability to use this X11/SSH session 244 if [ "$USE_XDIALOG" -a "$SSH_CONNECTION" -a "$DISPLAY" ]; then 245 f_have xauth || f_die 1 \ 246 "$msg_no_such_file_or_directory" "$pgm" "xauth" 247 local HOSTNAME displaynum 248 HOSTNAME=$(hostname) 249 displaynum="${DISPLAY#*:}" 250 xauth -f ~/.Xauthority extract - $HOSTNAME/unix:$displaynum \ 251 $HOSTNAME:$displaynum | sudo sh -c 'xauth -ivf \ 252 ~root/.Xauthority merge - > /dev/null 2>&1' 253 fi 254 255 # Re-execute ourselves with sudo(8) 256 f_dprintf "%s: Becoming root via sudo(8)..." mustberoot.subr 257 if [ $ARGC -gt 0 ]; then 258 exec sudo "$0" $ARGV 259 else 260 exec sudo "$0" 261 fi 262 exit $? # Never reached unless error 263} 264 265# f_authenticate_some_user 266# 267# Only used if running as root and requires X11 (see USE_XDIALOG below). 268# Prompts the user to enter a username and password to be authenticated via 269# sudo(8) to proceed. 270# 271# The following environment variables effect functionality: 272# 273# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate 274# that Xdialog(1) should be used instead of dialog(1). 275# 276f_authenticate_some_user() 277{ 278 local msg hline height width 279 280 f_have sudo || f_die 1 "$msg_must_be_root_to_execute" "$pgm" 281 282 # 283 # Secure-mode has been requested. 284 # 285 286 [ "$USE_XDIALOG" ] || f_die 1 "$msg_secure_mode_requires_x11" 287 [ "$(id -u)" = "0" ] || f_die 1 "$msg_secure_mode_requires_root" 288 289 # 290 # Prompt for sudo(8) credentials. 291 # 292 293 msg="$msg_please_enter_username_password" 294 hline="$hline_alnum_punc_tab_enter" 295 f_xdialog_2inputsbox_size height width \ 296 "$DIALOG_TITLE" \ 297 "$DIALOG_BACKTITLE" \ 298 "$msg" \ 299 "$field_username" "" \ 300 "$field_password" "" 301 height=$(( $height + 2 )) # Add height for --password 302 303 # 304 # Continue prompting until they either Cancel, succeed or exceed the 305 # number of allowed failures. 306 # 307 local user_pass nfailures=0 retval 308 while [ $nfailures -lt $PASSWD_TRIES ]; do 309 user_pass=$( $DIALOG \ 310 --title "$DIALOG_TITLE" \ 311 --backtitle "$DIALOG_BACKTITLE" \ 312 --hline "$hline" \ 313 --ok-label "$msg_ok" \ 314 --cancel-label "$msg_cancel" \ 315 --password --2inputsbox "$msg" \ 316 $height $width \ 317 "$field_username" "" \ 318 "$field_password" "" \ 319 2>&1 > /dev/null ) 320 retval=$? 321 322 # Catch X11-related errors 323 [ $retval -eq 255 ] && f_die $retval "$user_pass" 324 325 # Exit if the user cancelled. 326 [ $retval -eq $SUCCESS ] || exit $retval 327 328 # 329 # Make sure the user exists and is non-root 330 # 331 local user password 332 user="${user_pass%%/*}" 333 password="${user_pass#*/}" 334 unset user_pass # scrub memory 335 if [ ! "$user" ]; then 336 nfailures=$(( $nfailures + 1 )) 337 f_dialog_msgbox "$msg_no_username" 338 continue 339 fi 340 if [ ! "$SECURE_ALLOW_ROOT" ]; then 341 case "$user" in 342 root|toor) 343 nfailures=$(( $nfailures + 1 )) 344 f_show_msg "$msg_user_disallowed" "$user" 345 continue 346 esac 347 fi 348 if ! f_quietly id "$user"; then 349 nfailures=$(( $nfailures + 1 )) 350 if [ "$SECURE_DIVULGE_UNKNOWN_USER" ]; then 351 f_show_msg "$msg_unknown_user" "$user" 352 elif [ $nfailures -lt $PASSWD_TRIES ]; then 353 f_dialog_info "$msg_sorry_try_again" 354 sleep 1 355 fi 356 continue 357 fi 358 359 # 360 # Validate sudo(8) credentials for given user 361 # 362 su -m "$user" <<-EOF 363 sh <<EOS 364 sudo -k 365 sudo -S -v 2> /dev/null <<EOP 366 $password 367 EOP 368 EOS 369 EOF 370 retval=$? 371 unset user 372 unset password # scrub memory 373 374 if [ $retval -eq $SUCCESS ]; then 375 # Access granted... 376 break 377 else 378 # Access denied... 379 nfailures=$(( $nfailures + 1 )) 380 381 # introduce a short delay 382 if [ $nfailures -lt $PASSWD_TRIES ]; then 383 f_dialog_info "$msg_sorry_try_again" 384 sleep 1 385 fi 386 fi 387 done 388 389 # 390 # If user exhausted number of allowed password tries, log 391 # the security event and exit immediately. 392 # 393 if [ $nfailures -ge $PASSWD_TRIES ]; then 394 msg=$( printf "$msg_nfailed_attempts" "$nfailures" ) 395 logger -p auth.notice -t sudo " " \ 396 "${SUDO_USER:-$USER} : $msg" \ 397 "; TTY=$(tty)" \ 398 "; PWD=$PWD" \ 399 "; USER=root" \ 400 "; COMMAND=$0" 401 f_die 1 "sudo: $message" 402 fi 403} 404 405# f_mustberoot_init 406# 407# If not already root, make the switch to root by re-executing ourselves via 408# sudo(8) using user-supplied credentials. 409# 410# The following environment variables effect functionality: 411# 412# SECURE Either NULL or Non-NULL. If given a value will indicate 413# that (while running as root) sudo(8) authentication is 414# required to proceed. 415# 416f_mustberoot_init() 417{ 418 if [ "$(id -u)" != "0" -a ! "$SECURE" ]; then 419 f_become_root_via_sudo 420 elif [ "$SECURE" ]; then 421 f_authenticate_some_user 422 fi 423} 424 425############################################################ MAIN 426 427f_dprintf "%s: Successfully loaded." mustberoot.subr 428 429fi # ! $_MUSTBEROOT_SUBR
| 122 case "$mtag" in 123 X) # Cancel/Exit 124 f_die ;; 125 1) # Always try sudo(8) when run as $user 126 local err 127 if ! err=$( touch "$checkpath" 2>&1 ); then 128 f_dialog_msgbox "$err" 129 else 130 f_show_msg "$msg_created_path" "$checkpath" 131 fi 132 esac 133 else 134 # 135 # This user has created the path signing-off on sudo(8)-use 136 # but let's still give them a short/quick/unobtrusive reminder 137 # 138 f_dialog_info "$msg_becoming_root_via_sudo" 139 [ "$USE_XDIALOG" ] || sleep 0.6 140 fi 141 142 # 143 # Check sudo(8) access before prompting for password. 144 # 145 :| sudo -S -v 2> /dev/null 146 if [ $? -ne $SUCCESS ]; then 147 # 148 # sudo(8) access denied. Prompt for their password. 149 # 150 msg="$msg_please_enter_password" 151 hline="$hline_alnum_punc_tab_enter" 152 f_dialog_inputbox_size height width \ 153 "$DIALOG_TITLE" \ 154 "$DIALOG_BACKTITLE" \ 155 "$msg" \ 156 "$hline" 157 158 # 159 # Continue prompting until they either Cancel, succeed 160 # or exceed the number of allowed failures. 161 # 162 local password nfailures=0 retval 163 while [ $nfailures -lt $PASSWD_TRIES ]; do 164 if [ "$USE_XDIALOG" ]; then 165 password=$( $DIALOG \ 166 --title "$DIALOG_TITLE" \ 167 --backtitle "$DIALOG_BACKTITLE" \ 168 --hline "$hline" \ 169 --ok-label "$msg_ok" \ 170 --cancel-label "$msg_cancel" \ 171 --password --inputbox "$msg" \ 172 $height $width \ 173 2>&1 > /dev/null ) 174 retval=$? 175 176 # Catch X11-related errors 177 [ $retval -eq 255 ] && 178 f_die $retval "$password" 179 else 180 local dialog_inputbox 181 dialog_inputbox=$( $DIALOG \ 182 --title "$DIALOG_TITLE" \ 183 --backtitle "$DIALOG_BACKTITLE" \ 184 --hline "$hline" \ 185 --ok-label "$msg_ok" \ 186 --cancel-label "$msg_cancel" \ 187 --insecure \ 188 --passwordbox "$msg" \ 189 $height $width \ 190 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 191 ) 192 retval=$? 193 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 194 password=$( f_dialog_inputstr ) 195 fi 196 197 # Exit if the user cancelled. 198 [ $retval -eq $SUCCESS ] || exit $retval 199 200 # 201 # Validate sudo(8) credentials 202 # 203 sudo -S -v 2> /dev/null <<-EOF 204 $password 205 EOF 206 retval=$? 207 unset password # scrub memory 208 if [ $retval -eq $SUCCESS ]; then 209 # Access granted... 210 break 211 else 212 # Access denied... 213 nfailures=$(( $nfailures + 1 )) 214 215 # introduce a short delay 216 if [ $nfailures -lt $PASSWD_TRIES ]; then 217 f_dialog_info "$msg_sorry_try_again" 218 sleep 1 219 fi 220 fi 221 done 222 223 # 224 # If user exhausted number of allowed password tries, log 225 # the security event and exit immediately. 226 # 227 if [ $nfailures -ge $PASSWD_TRIES ]; then 228 msg=$( printf "$msg_nfailed_attempts" "$nfailures" ) 229 logger -p auth.notice -t sudo " " \ 230 "$USER : $msg" \ 231 "; TTY=$(tty)" \ 232 "; PWD=$PWD" \ 233 "; USER=root" \ 234 "; COMMAND=$0" 235 f_die 1 "sudo: $msg" 236 fi 237 fi 238 239 # Use xauth(1) to grant root the ability to use this X11/SSH session 240 if [ "$USE_XDIALOG" -a "$SSH_CONNECTION" -a "$DISPLAY" ]; then 241 f_have xauth || f_die 1 \ 242 "$msg_no_such_file_or_directory" "$pgm" "xauth" 243 local HOSTNAME displaynum 244 HOSTNAME=$(hostname) 245 displaynum="${DISPLAY#*:}" 246 xauth -f ~/.Xauthority extract - $HOSTNAME/unix:$displaynum \ 247 $HOSTNAME:$displaynum | sudo sh -c 'xauth -ivf \ 248 ~root/.Xauthority merge - > /dev/null 2>&1' 249 fi 250 251 # Re-execute ourselves with sudo(8) 252 f_dprintf "%s: Becoming root via sudo(8)..." mustberoot.subr 253 if [ $ARGC -gt 0 ]; then 254 exec sudo "$0" $ARGV 255 else 256 exec sudo "$0" 257 fi 258 exit $? # Never reached unless error 259} 260 261# f_authenticate_some_user 262# 263# Only used if running as root and requires X11 (see USE_XDIALOG below). 264# Prompts the user to enter a username and password to be authenticated via 265# sudo(8) to proceed. 266# 267# The following environment variables effect functionality: 268# 269# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate 270# that Xdialog(1) should be used instead of dialog(1). 271# 272f_authenticate_some_user() 273{ 274 local msg hline height width 275 276 f_have sudo || f_die 1 "$msg_must_be_root_to_execute" "$pgm" 277 278 # 279 # Secure-mode has been requested. 280 # 281 282 [ "$USE_XDIALOG" ] || f_die 1 "$msg_secure_mode_requires_x11" 283 [ "$(id -u)" = "0" ] || f_die 1 "$msg_secure_mode_requires_root" 284 285 # 286 # Prompt for sudo(8) credentials. 287 # 288 289 msg="$msg_please_enter_username_password" 290 hline="$hline_alnum_punc_tab_enter" 291 f_xdialog_2inputsbox_size height width \ 292 "$DIALOG_TITLE" \ 293 "$DIALOG_BACKTITLE" \ 294 "$msg" \ 295 "$field_username" "" \ 296 "$field_password" "" 297 height=$(( $height + 2 )) # Add height for --password 298 299 # 300 # Continue prompting until they either Cancel, succeed or exceed the 301 # number of allowed failures. 302 # 303 local user_pass nfailures=0 retval 304 while [ $nfailures -lt $PASSWD_TRIES ]; do 305 user_pass=$( $DIALOG \ 306 --title "$DIALOG_TITLE" \ 307 --backtitle "$DIALOG_BACKTITLE" \ 308 --hline "$hline" \ 309 --ok-label "$msg_ok" \ 310 --cancel-label "$msg_cancel" \ 311 --password --2inputsbox "$msg" \ 312 $height $width \ 313 "$field_username" "" \ 314 "$field_password" "" \ 315 2>&1 > /dev/null ) 316 retval=$? 317 318 # Catch X11-related errors 319 [ $retval -eq 255 ] && f_die $retval "$user_pass" 320 321 # Exit if the user cancelled. 322 [ $retval -eq $SUCCESS ] || exit $retval 323 324 # 325 # Make sure the user exists and is non-root 326 # 327 local user password 328 user="${user_pass%%/*}" 329 password="${user_pass#*/}" 330 unset user_pass # scrub memory 331 if [ ! "$user" ]; then 332 nfailures=$(( $nfailures + 1 )) 333 f_dialog_msgbox "$msg_no_username" 334 continue 335 fi 336 if [ ! "$SECURE_ALLOW_ROOT" ]; then 337 case "$user" in 338 root|toor) 339 nfailures=$(( $nfailures + 1 )) 340 f_show_msg "$msg_user_disallowed" "$user" 341 continue 342 esac 343 fi 344 if ! f_quietly id "$user"; then 345 nfailures=$(( $nfailures + 1 )) 346 if [ "$SECURE_DIVULGE_UNKNOWN_USER" ]; then 347 f_show_msg "$msg_unknown_user" "$user" 348 elif [ $nfailures -lt $PASSWD_TRIES ]; then 349 f_dialog_info "$msg_sorry_try_again" 350 sleep 1 351 fi 352 continue 353 fi 354 355 # 356 # Validate sudo(8) credentials for given user 357 # 358 su -m "$user" <<-EOF 359 sh <<EOS 360 sudo -k 361 sudo -S -v 2> /dev/null <<EOP 362 $password 363 EOP 364 EOS 365 EOF 366 retval=$? 367 unset user 368 unset password # scrub memory 369 370 if [ $retval -eq $SUCCESS ]; then 371 # Access granted... 372 break 373 else 374 # Access denied... 375 nfailures=$(( $nfailures + 1 )) 376 377 # introduce a short delay 378 if [ $nfailures -lt $PASSWD_TRIES ]; then 379 f_dialog_info "$msg_sorry_try_again" 380 sleep 1 381 fi 382 fi 383 done 384 385 # 386 # If user exhausted number of allowed password tries, log 387 # the security event and exit immediately. 388 # 389 if [ $nfailures -ge $PASSWD_TRIES ]; then 390 msg=$( printf "$msg_nfailed_attempts" "$nfailures" ) 391 logger -p auth.notice -t sudo " " \ 392 "${SUDO_USER:-$USER} : $msg" \ 393 "; TTY=$(tty)" \ 394 "; PWD=$PWD" \ 395 "; USER=root" \ 396 "; COMMAND=$0" 397 f_die 1 "sudo: $message" 398 fi 399} 400 401# f_mustberoot_init 402# 403# If not already root, make the switch to root by re-executing ourselves via 404# sudo(8) using user-supplied credentials. 405# 406# The following environment variables effect functionality: 407# 408# SECURE Either NULL or Non-NULL. If given a value will indicate 409# that (while running as root) sudo(8) authentication is 410# required to proceed. 411# 412f_mustberoot_init() 413{ 414 if [ "$(id -u)" != "0" -a ! "$SECURE" ]; then 415 f_become_root_via_sudo 416 elif [ "$SECURE" ]; then 417 f_authenticate_some_user 418 fi 419} 420 421############################################################ MAIN 422 423f_dprintf "%s: Successfully loaded." mustberoot.subr 424 425fi # ! $_MUSTBEROOT_SUBR
|