Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #Written by Manuel Iglesias. glesialo@gmail.com
- CommandName=${0##*/}
- TempDir=/tmp
- HomeBasePath="/home"
- TempXSessionErrorsFileName=".xsession-errors"
- TempXAuthorityFileName=".Xauthority"
- UserNamePlaceHolder="USERNAME"
- DefaultAskForPasswordMessage="Please type $UserNamePlaceHolder password."
- UserOption="--user"
- UserOptionMissingMessage="Missing user's name"
- MessageOption="--message"
- MessageOptionMissingMessage="Missing message string"
- DefaultMissingMessage="Missing string"
- English_LANG=en_IE.UTF-8
- English_LANGUAGE=en_IE:en
- SuAuthenticationFailureMessage="su: Authentication failure"
- Dialog_MessageTimedTimeout=5 # In seconds.
- WrongPasswordMessage="ERROR: Incorrect password."
- #Functions. BEGIN.
- echoE()
- {
- echo -e "$@" 1>&2 # If run in a X window application: writes to XsessionErrorsFile
- Dialog_MessageTimed --title "$CommandName-$$" --timeout $Dialog_MessageTimedTimeout "$(echo -e "$@")" &>/dev/null &
- return 0
- }
- Exit() # $1: Script ExitCode
- {
- if [ -n "$Old_DBUS_SESSION_BUS_ADDRESS" ]
- then
- export DBUS_SESSION_BUS_ADDRESS=$Old_DBUS_SESSION_BUS_ADDRESS
- fi
- if [ -n "$Old_XAUTHORITY" ]
- then
- export XAUTHORITY=$Old_XAUTHORITY
- fi
- if [ -n "$Old_USER" ]
- then
- export USER=$Old_USER
- fi
- if [ -n "$Old_HOME" ]
- then
- export HOME=$Old_HOME
- fi
- if [ -n "$Old_LANG" ]
- then
- export LANG=$Old_LANG
- fi
- if [ -n "$Old_LANGUAGE" ]
- then
- export LANGUAGE=$Old_LANGUAGE
- fi
- if [ -f "$TempXAuthorityFile" ]
- then
- if ! rm $TempXAuthorityFile &>/dev/null
- then
- echoE "$CommandName-$$: Warning! Can't remove temporary \$XAUTHORITY file."
- fi
- fi
- if [ -f "$TempXSessionErrorsFile" ]
- then
- if [ -s "$TempXSessionErrorsFile" ] # If more than 0 bytes
- then
- while read Line
- do
- echo "$CommandName-$$: $Line"
- done < "$TempXSessionErrorsFile"
- fi
- if ! rm $TempXSessionErrorsFile &>/dev/null
- then
- echoE "$CommandName-$$: Warning! Can't remove '$TempXSessionErrorsFile' file."
- fi
- fi
- echo "$CommandName-$$: Exit code: $1."
- echo "#### $CommandName-$$. END." # Mark end of output
- exit $1 # This is not a mistake. Here the whole script exits.
- }
- Usage()
- {
- echoE "'$CommandName' lets user run a (graphical) Command as a different user (UserName) if the correct
- password is given. If no UserName is supplied, '$CommandName' will run the given Command as 'root'.
- Command will run with the same environment UserName would have after login.
- Usage: '$CommandName [Options] Command [CommandParameters]'.
- Options:
- [$UserOption UserName] (Command will run for UserName).
- [$MessageOption request_password_message] (will replace the default message).
- Note: StdOut & StdError will be redirected to (invoking user's) '\$HOME/$TempXSessionErrorsFileName'."
- return 0
- }
- #Functions. END.
- if [ $# -lt 1 ] || [ "$1" == "-h" ] || [ "$1" == "-?" ] || [ "$1" == "--help" ] || [ "$1" == "-help" ]
- then
- Usage
- exit 64
- fi
- #Mark beginning of output. BEGIN.
- CommandLine="$CommandName"
- for Param in "$@"
- do
- Substrings=0
- for SubString in $Param
- do
- let Substrings++
- done
- if [ $Substrings -gt 1 ]
- then
- CommandLine=$CommandLine" \"$Param\""
- else
- CommandLine=$CommandLine" $Param"
- fi
- done
- echo -e "#### $CommandName-$$. BEGIN.\n$CommandName-$$.CmmdLine:>$CommandLine<"
- CommandLine=""
- #Mark beginning of output. END.
- #!! Use 'Exit' instead of 'exit' from now on to remove temporary files and mark end of output
- #Temporary XSessionErrorsFile file. BEGIN.
- if ! TempXSessionErrorsFile=$(mktemp ${TempDir}/${CommandName}${TempXSessionErrorsFileName}.XXXXXXXX 2>/dev/null) # Copy different for each instance of script.
- then
- echoE "$CommandName-$$: Failed to create temporary '$TempXSessionErrorsFileName' file. Aborting."
- Exit 73
- fi
- if ! chmod 666 $TempXSessionErrorsFile 2>/dev/null
- then
- echoE "$CommandName-$$: Can't change permissions of '$TempXSessionErrorsFile'. Aborting."
- Exit 77
- fi
- #Temporary XSessionErrorsFile file. END.
- #Temporary $XAUTHORITY file. BEGIN.
- if [ -z "$XAUTHORITY" ] || ! [ -f "$XAUTHORITY" ]
- then
- echoE "$CommandName-$$: \$XAUTHORITY file does not exist. Aborting."
- Exit 70
- fi
- if ! TempXAuthorityFile=$(mktemp ${TempDir}/${CommandName}${TempXAuthorityFileName}.XXXXXXXX 2>/dev/null)
- then
- echoE "$CommandName-$$: Failed to create temporary '$TempXAuthorityFileName' file. Aborting."
- Exit 73
- fi
- if ! cp -f $XAUTHORITY $TempXAuthorityFile 2>/dev/null #Current file in $XAUTHORITY has 600 permissions and, therefore, is only readable by its owner
- then
- echoE "$CommandName-$$: Can't copy \$XAUTHORITY file. Aborting."
- Exit 73
- fi
- if ! chmod 644 $TempXAuthorityFile 2>/dev/null # Read permissions to all
- then
- echoE "$CommandName-$$: Can't change permissions of temporary \$XAUTHORITY file. Aborting."
- Exit 77
- fi
- #Temporary $XAUTHORITY file. END.
- RunWithLoginEnvironmentScript=$(which -a RunWithLoginEnvironment 2>/dev/null) # which: Path/File needed
- if [ ! -f "$RunWithLoginEnvironmentScript" ]
- then
- echoE "$CommandName-$$: RunWithLoginEnvironmentScript 'RunWithLoginEnvironment' script not found. Aborting."
- Exit 127
- fi
- #Read strings and remove UserOption & MessageOption. BEGIN.
- OptionMessageValue="";OptionUserValue="";Parameters="";VariableToRead="";WaitingForString=false
- for Parameter in "$@"
- do
- if $WaitingForString
- then
- eval "$VariableToRead=\"$Parameter\""
- VariableToRead=""
- WaitingForString=false
- else
- if [ "$Parameter" == "$UserOption" ]
- then
- WaitingForString=true
- VariableToRead="OptionUserValue"
- else
- if [ "$Parameter" == "$MessageOption" ]
- then
- WaitingForString=true
- VariableToRead="OptionMessageValue"
- else
- Parameters=${Parameters}"\"$Parameter\" "
- fi
- fi
- fi
- done
- if $WaitingForString && [ -n "$VariableToRead" ]
- then
- case "$VariableToRead" in
- OptionUserValue) echoE "$CommandName-$$: $UserOptionMissingMessage";;
- OptionMessageValue) echoE "$CommandName-$$: $MessageOptionMissingMessage";;
- *) echoE "$CommandName-$$: $DefaultMissingMessage";;
- esac
- Exit 64
- fi
- eval "set -- $Parameters" # To interpret correctly parameter values with spaces
- #Read strings and remove UserOption & MessageOption. END.
- Old_USER=$USER
- Old_HOME=$HOME
- if [ -z "$OptionUserValue" ]
- then
- OptionUserValue=root
- fi
- if IsRegisteredUser "$OptionUserValue"
- then
- export USER=$OptionUserValue
- else
- echoE "$CommandName-$$: '$OptionUserValue' is not a registered user. Aborting."
- Exit 67
- fi
- if [ "$USER" == "$Old_USER" ]
- then
- echoE "$CommandName-$$: '$OptionUserValue' is already the current user. Aborting."
- Exit 67
- fi
- if [ "$USER" == "root" ]
- then
- export HOME="/${USER}"
- else
- export HOME=${HomeBasePath}/${USER}
- fi
- if [ ! -d "$HOME" ]
- then
- echoE "$CommandName-$$: ${USER}'s \$HOME not found. Aborting."
- Exit 70
- fi
- if [ $# -eq 0 ]
- then
- echoE "$CommandName-$$: No Command to run. Aborting."
- Exit 127
- fi
- if [ -n "$OptionMessageValue" ]
- then
- AskForPasswordMessage="$OptionMessageValue"
- else
- AskForPasswordMessage=${DefaultAskForPasswordMessage/$UserNamePlaceHolder/${USER}\'s}
- fi
- if ! Password=$(Dialog_InputText --title "$CommandName-$$" --hide-entry-text "$AskForPasswordMessage" 2>/dev/null)
- then
- echoE "$CommandName-$$: Failed to read password. Aborting."
- Exit 90
- fi
- Old_XAUTHORITY=$XAUTHORITY
- export XAUTHORITY=$TempXAuthorityFile
- Old_LANG=$LANG
- Old_LANGUAGE=$LANGUAGE
- if [ -z "$Old_LANGUAGE" ]
- then
- Old_LANGUAGE=$Old_LANG
- fi
- Old_DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS
- export -n DBUS_SESSION_BUS_ADDRESS="" # Unset + export: Remove from environment. Some applications (I.E.: DefaultTerminalEmulator) refuse to start otherwise.
- LANG=$English_LANG # expect expects English su's messages
- LANGUAGE=$English_LANGUAGE # expect expects English su's messages
- ExpectOut=$(expect - "$@" <<HereDoc
- set force_conservative 1 ;# set to 1 to force conservative mode even if
- ;# script wasn't run conservatively originally
- if {\$force_conservative} {
- set send_slow {1 .1}
- proc send {ignore arg} {
- sleep .1
- exp_send -s -- \$arg
- }
- }
- set timeout -1
- set argsstring ""
- foreach a \$argv {
- append argsstring "\"\${a}\" " ;# argsstring: "arg 1" "arg 2" ...
- }
- spawn \$env(SHELL)
- match_max 100000
- spawn -noecho su $USER -c "&>$TempXSessionErrorsFile LANG=$Old_LANG LANGUAGE=$Old_LANGUAGE $RunWithLoginEnvironmentScript \$argsstring"
- expect "assword:"
- send {ignore arg} "$Password\r"
- expect eof
- catch wait result
- exit [lindex \$result 3]
- HereDoc
- )
- ExitCode=$?
- if [ "$ExpectOut" != "${ExpectOut/${SuAuthenticationFailureMessage}/}" ] # $SuAuthenticationFailureMessage found in expect output
- then
- echoE "$CommandName-$$: $WrongPasswordMessage"
- Exit 77
- else
- Exit $ExitCode # Necessary to remove temporary files.
- fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement