How can I use the root password provided by the user in my bash installation script - bash

I'm trying to install a cronjob to run a bash shell script on a relative's machine. They will run the install and I can't access it remotely yet (that's what my script is for - but that's not the issue here). I use kdialog to request their root password and then want to use that to sudo various commands. My code below is failing by a) revealing the root p/w on the terminal and b) failing to pipe it to the various sudos. Help?
#!/bin/bash
kdialog --password "Please enter your root password to install theCronScript.sh and set up cron"
# Sanity checks =========================================╕
if test -z "$BASH" ; then
printf "$SCRIPT:$LINENO: please run this script with the BASH shell\n">&2
exit 192
fi
#========================================================╛
# Global variables=======================================╕
PW="$?"
THISDIR="$(pwd)"
GETIPFILE='theCronScript.sh'
CRONPERIOD='/15 * * * * '
TARGETCRONDIR='/etc/cron.hourly'
#========================================================╛
echo "hi"
# txt file exists check =================================╕
echo "Checking:"
if [ ! -f "$THISDIR/$GETIPFILE" ]; then #there's no file to install
kdialog --msgbox "I cannot find $GETIPFILE to upload\nPlease check attachments in recent e-mails from Greg and download $GETIPFILE to $THISDIR"
exit
else
if [ -f "$TARGETCRONDIR/$GETIPFILE" ]; then #the target already exists
kdialog --title "Replace or Keep" --warningyesno "A similar file already exists.\n Do you want to replace it (recommended)?\n(The original file will be saved with a different name _OLD)"
if [ $? = 0 ]; then # rename, then replace the existing file
#echo $PW is probably unneccessary beyond the first use but just in case...
RNGETIPFILE=$GETIPFILE'_OLD'
echo $PW | sudo -S mv $TARGETCRONDIR/$GETIPFILE $TARGETCRONDIR/$RNGETIPFILE #rename original file
echo $PW | sudo -S cp $THISDIR/$GETIPFILE $TARGETCRONDIR/$GETIPFILE #copy new version in
echo $PW | sudo -S chmod +x $TARGETCRONDIR/$GETIPFILE #
echo $PW | sudo -S crontab -l > mycron #write out current crontab
echo $PW | sudo -S echo $CRONPERIOD $TARGETCRONDIR >> mycron #echo new cron into cron file
echo $PW | sudo -S crontab mycron #install new cron file
rm mycron
$PW="" #clear password variable once it's no longer required
else # Don't replace, exit
exit
fi
else # Nothing to replace. Just copy it in
echo $PW | sudo -S "cp $THISDIR/$GETIPFILE $TARGETCRONDIR/$GETIPFILE" #copy new version in
echo $PW | sudo -S chmod +x $TARGETCRONDIR/$GETIPFILE # make sure it's executable
echo $PW | sudo -S crontab -l > mycron #write out current crontab
echo $PW | sudo -S echo $CRONPERIOD $TARGETCRONDIR >> mycron #echo new cron into cron file
echo $PW | sudo -S crontab mycron #install new cron file
rm mycron
$PW="" #clear password variable once it's no longer required
fi
fi
exit 0
#========================================================╛

One option is to ask for the password directly in the sudo command via an external GUI. From the sudo manpage:
-A, --askpass
Normally, if sudo requires a password, it will read it from the user's terminal. If the -A (askpass) option is specified, a (possibly graphical)
helper program is executed to read the user's password and output the password to the standard output. If the SUDO_ASKPASS environment variable is
set, it specifies the path to the helper program. Otherwise, if sudo.conf(5) contains a line specifying the askpass program, that value will be
used. For example:
# Path to askpass helper program
Path askpass /usr/X11R6/bin/ssh-askpass
If no askpass program is available, sudo will exit with an error.
if sudo is caching credentials, it will only ask for this password once. One way I use to get this cached would be, having no side effects other than caching the password:
export SUDO_ASKPASS=/usr/bin/ssh-askpass
sudo --askpass true
Depending on what distro you're running, ssh-askpass may be somewhere else. There is an example on StackExchange on how you might use kdialog to get the password for the sudo askpass. For reference, here is the script:
$ cat myaskpass.sh
#!/bin/bash
kdialog --password "Please enter your password: "
exit 0
And how you would use it:
export SUDO_ASKPASS=/path/to/myaskpass.sh
sudo --askpass true

Related

bash script to log as another user and keep the terminal open

I have set up a http server at localhost, with several sites. I would like to connect to each site root folder, at the same way I used to at a remote server via ssh. So, I tried to create a bash script, intended to log as user "http", giving the site root folder as argument and change the $HOME to the site root folder:
#!/bin/bash
echo "Connecting to $1 as http...";
read -p "Contraseña: " -s pass;
su - http << EOSU >/dev/null 2>&1
$pass
export HOME="/srv/http/$1";
echo $HOME;
source .bash_profile;
exec $SHELL;
EOFSU
It does not work, basically because of:
echo $HOME keeps giving out the home folder of the user launching the script.
when the script reaches the end, it ends (obvious), but I would like that it stays open, so I could have a terminal session for user "http" and go on typing commands.
In other words, I am looking for a script that saves me 3 commands:
# su - http
# cd <site_root_folder>
# export HOME=<site_root_folder>
Edit:
Someone suggested the following:
#!/bin/bash
init_commands=(
"export HOME=/srv/http/$(printf '%q' "$1")"
'cd $HOME'
'. .bash_profile'
)
su http -- --init-file <(printf '%s\n' "${init_commands[#]}")
I am sorry but their post is gone... In any case, this give me out bash: /dev/fd/63: permission denied. I am not so skillful to understand the commands above and try to sort it out. Can someone help me?
Thanks.
Possible solution:
I have been playing around, based on what was posted and some googling, and finally I got it :-)
trap 'rm -f "$TMP"' EXIT
TMP=$(mktemp) || exit 1
chmod a+r $TMP
cat >$TMP <<EOF
export HOME=/srv/http/$(printf '%q' "$1")
cd \$HOME
. .bash_profile
EOF
su http -- --init-file $TMP
I admit it is not a nice code, because of:
the temporary file is created by the user executing the script and later I have to chmod a+r so user "http" can access... not so good.
I am sure this can be done on the fly, without creating a tmp file.
If some can improve it, it will be welcome; although in any case, it works!
Your main problem is that the $HOME is evaluated as when the user run the script, meaning that it will get his evaluation of $HOME instead of evaluating it as the given user.
You can evaluate the $HOME as the given user (using the eval command) but I wont recommend it, it is generally bad practice to use this kind of evaluation, especially when talking about security.
I can recommend you to get the specific user home directory with standard linux tools like passwd
Example of the behavior you are seeing:
# expected output is /home/eliott
$ sudo -u eliott echo $HOME
/root
Working it around with passwd:
$ sudo -u eliott echo $(getent passwd eliott | cut -d: -f6)
/home/eliott

How to handle additional files when building and running a AUR package?

So I was just playing around and created this simple Shell script:
TestScript.sh
#!/bin/bash
read -p "read or write? " INP
if [[ "${INP}" == "write" ]]
then
read -p "Write your text: " TEXT
touch /usr/share/textfile.txt
echo "${TEXT}" >> /usr/share/textfile.txt
else
cat /usr/share/textfile.txt
fi
which of course can easily read and write into a file under /usr after gaining sudo priviliges:
sudo sh TestScript.sh
Based on this file I create a test PKGBUILD to install TestScript.sh via pacman later on:
PKGBUILD
# Maintainer: Your Name <youremail#domain.com>
pkgname='test-script'
pkgver=1
pkgrel=1
pkgdesc="AUR test package"
arch=('x86_64')
license=('custom')
source=('TestScript.sh')
md5sums=('SKIP')
package() {
mkdir -p "${pkgdir}/usr/bin"
cp "${srcdir}/TestScript.sh" "${pkgdir}/usr/bin/TestScript"
chmod +x "${pkgdir}/usr/bin/TestScript"
}
Followed by
makepkg
sudo pacman -U test-script-1-1-x86_64.pkg.tar.xz
I can run
TestScript
from the command line. But just as I thought, I am unable to write into /usr/share/textfile.txt .
I was searching the Arch-Wiki page up and down, but I couldn't find out how to handle this situation. I basically just want to have a location where I can properly read and write a file without messing up the user space.
Does anyone have an idea?

Starting Midnight Commander `mc` with sudo alias and preserve path

Is it possible to start the mc-wrapper with sudo and still use the last selected directory on the console when quitting sudo mc (requirement number 4)? My default alias looks like this.
alias mc='EDITOR="${EDITOR-mcedit}" . /usr/lib/mc/mc-wrapper.sh'
Some errors (for the Googlers)
sudo: mc: command not found
sudo: .: command not found # "." == "source"
My requirements
Ubuntu 18.04.1.
The alias should work with and without sudo call.
If possible, a single alias for mc in /etc/bash.bashrc for all users.
The directory you changed to with sudo mc should be "preserved" after closing the Midnight Commander. This means that you will not be in the same directory as you started sudo mc (provided it is not the same directory).
Optional requirements
See if the alias was started with super powers.
See if the alias was started with sudo.
If the alias mc was started without super powers or sudo, ask if the program mc should still be started with sudo rights.
If the question is answered No, use my default alias.
In all other cases, the first four requirements should be met.
The editor (e.g. mcedit or vi) within mc should be selectable via another alias like mcvi (for vi) without code duplication.
Arguments should be passed on to the program, like sudo mc /opt/ /mnt/
Here's one hacky solution (tested, but the last two optional requirements are still missing).
/etc/bash.bashrc
alias sudo='sudo ' # fixes "sudo: mc: command not found" (breaks with an argument: sudo -H ll)
# sudo apt update && sudo apt install dialog mc pwgen
#
# Start the alias with a "real" command (instead of a shell keyword like "if") so that sudo is not confused.
# This first command (env) will eat sudo and all arguments! Even the following file redirection including the angle bracket is already executed without sudo.
alias mc='env > "/tmp/mc.env.$(whoami).$$"
MC_USER="$(whoami)"
MC_ENV_FILE="/tmp/mc.env.${MC_USER}.$$"
# cat "${MC_ENV_FILE}"
if [ "$(cat "${MC_ENV_FILE}" | grep "$(id -nu 0)" | wc -l)" -gt "3" ]; then
# echo "This alias was called with super powers."
MC_ROOT="root"
fi
if [ "$(cat "${MC_ENV_FILE}" | grep "^SUDO_" | wc -l)" -gt "3" ]; then
# echo "This alias was called with sudo (possibly sudo -i or sudo -s was entered before)."
MC_SUDO="sudo"
fi
if [ "${MC_ROOT}" == "root" ] || [ "${MC_SUDO}" == "sudo" ]; then
MC_DIALOG="0"
else
# echo "This alias was called as normal user."
dialog --cr-wrap --defaultno --title "sudo mc" --yesno "Do you want super powers (sudo/root)?\n\n(Alternatively you can use \"sudo mc\" directly next time.)\n\nAgain: Do you want super powers (sudo/root)?" 9 64
MC_DIALOG="$?"
tput reset
fi
if [ "${MC_DIALOG}" != "0" ]; then
# echo "No, do not use sudo and stay normal user."
# echo "Standard wrapper (without arguments)..."
EDITOR="${EDITOR-mcedit}" . /usr/lib/mc/mc-wrapper.sh # does not work with sudo because "." is not a program like "ls" or "grep"!
else
# echo "Yes, exec those decisive commands with super powers."
# echo "Custom wrapper (also without arguments)..."
MC_PWD_FILE_DIRNAME="${TMPDIR-/tmp}/mc-${MC_USER}/"
MC_PWD_FILE="${MC_PWD_FILE_DIRNAME}mc.pwd.$$.$(pwgen 13 1)"
sudo mkdir -p "$MC_PWD_FILE_DIRNAME"
sudo chown "$(sudo whoami)":"$(sudo whoami)" "$MC_PWD_FILE_DIRNAME"
sudo chmod 0700 "$MC_PWD_FILE_DIRNAME"
sudo EDITOR="${EDITOR-mcedit}" /usr/bin/mc -P "$MC_PWD_FILE"
sudo chown -R "$MC_USER":"$MC_USER" "$MC_PWD_FILE_DIRNAME"
if test -r "$MC_PWD_FILE"; then
MC_PWD=$(cat "$MC_PWD_FILE")
if test -n "$MC_PWD" && test -d "$MC_PWD"; then
cd "$MC_PWD"
fi
unset MC_PWD
fi
rm -f "$MC_PWD_FILE"
unset MC_PWD_FILE
unset MC_PWD_FILE_DIRNAME
fi
unset MC_DIALOG
unset MC_SUDO
unset MC_ROOT
rm -f "${MC_ENV_FILE}"
unset MC_ENV_FILE
unset MC_USER
# This terminating line break is required:
'
I didn't manage to use a function mcwrapper (and $(declare -f mcwrapper)) and I don't think it's that easy either!?

script a shell script that test that the new user can indeed upload and download files using passive mode of operation in proftpd

I need a shell script that test that the new user can indeed upload and download files using passive mode of operation in proftpd.I had installed proftpd on /tmp and configuration file is /etc/proftpd.conf.
please guys help me out here
#! /bin/bash
#decompress the file
mkdir /opt/$1
cd /opt/$1
wget http://ftp.swin.edu.au/proftpd/distrib/source/proftpd-1.3.3e.tar.gz
tar -xzf proftpd-1.3.3e.tar.gz
#configure it
cd proftpd-1.3.3e
./configure --sysconfdir=/opt
#Make the file
make
#make install the extracted file
make install
#To add ftp user,group
useradd $2
groupadd $2
mkdir /home/$3
passwd $2
echo "User $3 ">> /opt/proftpd.conf
echo "Group $3 ">> /opt/proftpd.conf
echo "DefaultRoot ~ " >> /opt/proftpd.conf
echo "PassivePorts 30000 35000 ">> /opt/proftpd.conf
exit
echo -n "Enter FTP Username : "
read USER
echo -n "Enter password : "
read -s PASSWD
HOST='192.168.1.100'
ftp -n -v $HOST << EOT
ascii
user $USER $PASSWD
prompt
put file.txt
get file.txt
ls -la
bye
EOT

Should this be done with bash script or automator or applescript?

I have bash command that contains a variable to a file which updates the firmware for a specific hardware and give it a serial number.
#!/bin/bash
fpath=$(dirname "$0")
ee_image=mlr-2000119.bin
sudo nvram tbt-options=4
sudo /usr/sbin/bless -mount / -firmware "$fpath/ThorUtilDevice.efi" -payload "$fpath/$ee_image" -options "-o -ej 1 -blast efi-apple-payload0-data"
sudo reboot now
I would like to create a file through automator or applescript that will create this same file but will automatically increase the ee_image bin file name by one. So that the end user doesn't always have to open the command file in text edit, make the change manually then save then execute the file..
Any help with this would be a God send.
The last line in your script sudo reboot now would make any sort of loop meaningless.
However, if you insist, use may a loop:
#!/bin/bash
fpath=$(dirname "$0")
for i in {2000119..3000119}; do
ee_image=mlr-${i}.bin
sudo nvram tbt-options=4
sudo /usr/sbin/bless -mount / -firmware "$fpath/ThorUtilDevice.efi" -payload "$fpath/$ee_image" -options "-o -ej 1 -blast efi-apple-payload0-data"
sudo reboot now
done
This would loop through mlr-2000119.bin to mlr-3000119. You can also consider passing an argument to the script in which case you can use your original script with the ee_image line as
ee_image=mlr-$1.bin
and invoke bash /path/to/your/script.sh 2000119
#devnull wrote:
The last line in your script sudo reboot now would make any sort of loop meaningless.
I believe that the reboot command is just like any other command. It should be echoed to a file rather than being run to generate the script for the end-user.
I think that a good idea would be to have a script that creates scripts.
This is similar to how many websites work. The script on the server can echo HTML, CSS, and JavaScript code for consumption by the web browser.
Here is an example:
#!/bin/bash
# set the path to the dir
dir=$(dirname $0)"/"
# set the path to the file that keeps track of the serial numbers
snFile="$dir""sn.txt"
# set the file name of the file to be generated
fileName="serialize"
# read the last serial number used
if [ -e "$snFile" ];
then
read lastSN < "$snFile"
else
lastSN="0"
fi
# increment the serial number
let "nextSN = $lastSN + 1"
echo "$nextSN" > "$snFile"
# create a path variable for the file being created.
generatedPath="$dir$fileName$nextSN.sh"
# generate the script
echo "#!/bin/bash" > "$generatedPath"
echo 'fpath=$(dirname "$0")' >> "$generatedPath"
echo '' >> "$generatedPath"
echo "ee_image=mlr-$nextSN.bin" >> "$generatedPath"
echo '' >> "$generatedPath"
echo 'sudo nvram tbt-options=4' >> "$generatedPath"
echo '' >> "$generatedPath"
echo 'sudo /usr/sbin/bless -mount / -firmware \"$fpath/ThorUtilDevice.efi\" -payload \"$fpath/$ee_image\" -options \"-o -ej 1 -blast efi-apple-payload0-data\" \' >> "$generatedPath"
echo '' >> "$generatedPath"
echo 'sudo reboot now' >> "$generatedPath"
# give the user some feedback
echo "generatedPath: $generatedPath"
If having your end-user run a bash script is good enough, then I think that you're almost done.
If you want to have an even better user interface and have a Mac application for the end-user to run, send me an email and I can help you with that.
kaydell#learnbymac.com

Resources