Catch invalid password on Sudo - try-catch

Is there a way to trap/catch a invalid password when you use sudo? Basically I want to return a specific exit code if the sudo password is invalid. I don't want to avoid sudo or get around it, I just want to close/exit a script in a matter of my choosing.

Based on the man page of sudo(8), there is no easy way for evaluating the exact error reasons for a failure:
Exit Value
Upon successful execution of a program, the exit status from sudo will
simply be the exit status of the program that was executed.
Otherwise, sudo exits with a value of 1 if there is a
configuration/permission problem or if sudo cannot execute the given
command. In the latter case the error string is printed to the
standard error. If sudo cannot stat(2) one or more entries in the
user's PATH, an error is printed on stderr. (If the directory does not
exist or if it is not really a directory, the entry is ignored and no
error is printed.) This should not happen under normal circumstances.
The most common reason for stat(2) to return ''permission denied'' is
if you are running an automounter and one of the directories in your
PATH is on a machine that is currently unreachable.
The only "ugly" approach, which comes to my mind is to parse the result of stderr to determine the error reason:
#!/bin/bash
tmpfile=`mktemp`
sudo echo "dummy" 2>$tmpfile
if [ $? == 1 ]; then
if [ `cat $tmpfile | grep -x "sudo.*incorrect password attempts" | wc -l` == 1 ]; then
# exit due to failed password attempts
echo "too many failed password attempts"
else
# other reason, for instance configuration
echo "other reason"
fi
fi
rm $tmpfile
Note, however, that this approach is not upgrade-safe and moreover language-dependent: If a patch to sudo changes the text which is shown to the user in case of a wrong password, or the user logs on in a different language, this coding will not be able to handle this properly.

Related

psql -v ON_ERROR_STOP=1 not working, cannot terminate script execution

I have a bash script that calls another script containing a psql command, i want to stop executing when the psql command fails. The below psql call is to execute a postgres function.
In below script the echo $exitcode always returns 0 even if script calling postgres function returns a error. I want psql command to return right error code, so i can handle it properly in below script.
FirstScript:
list=`sh /opt/dbb_promo_list.sh -60 -30`
ID_LIST=`echo $list |sed 's/[a-z _-]*//g'|sed 's/(.*//g'`
exitcode=$?
echo $exitcode //always returns 0 both in successful and error case, i want it to return corresponding exit code for error, so i can handle it and stop the script.
if [ $exitcode -ne 0 ] ; then
echo "There seems to have errors while running script "
echo "Exit code is : "$exitcode
exit 1
fi
dbb_promo_list.sh : This script contains the following command
psql -U $DB_USERNAME -h $DB_HOST -p $DB_PORT -d $DATABASE -c "SELECT schema.${PROCEDURE}($day_begin,$day_end)"
Error thrown below when calling the above command. Since this error is thrown the psql command shouldnt return exit code 0 but its not the case, it returns 0 even if the postgres function works fine or returns a error like below. I am not sure if there a way to tweak in bash script to recognize a error is thrown
ERROR: function string_agg(numeric, unknown) does not exist
LINE 1: SELECT string_agg(pmotn_id, ',') FROM ppcapr.p...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
When the sql function fails. It then reports the error on the console, but continues to proceed with executing remainder of the script. But i want the script execution to terminate once the error occurs.
Any suggestions?

Shell script for checking if array is empty and restarting program if so

I want to make a shell script that keeps running to check if my two light weight web servers are still running, and restart them if one is not.
I can use the the command pgrep -f thin to get an array (?) of pids of my server called thin.
When this returned array has a count of zero I want to run a command which starts both servers:
cd [path_to_app] && bundle exec thin -C app_config.yml start
pgrep -f thin returns all the pids of the servers that are running. For example:
2354223425
I am new to shell scripting and don't know how to store the results of pgrep-f thin in an array. E.g.,
#!/bin/sh
while true
do
arr=$(pgrep -f thin) # /edited and now THIS WORKS!
#Then I want to check the length of the array and when it is empty run the above
#command, e.g.,
if [ ${#arr[#]} == 0 ]; then
cd [path_to_app] && bundle exec thin -C app_config.yml start
fi
#wait a bit before checking again
sleep 30
done
The first problem I have is that I cannot store the pgrep values in an array, and I am not sure if I can check against zero values. After that I am not sure if there are problems with the other code. I hope someone can help me!
You forgot to execute the command:
arr=($(pgrep -f thin))
[...] when it is empty
If you only check for emptyness, you can directly use the exit status of grep.
-q, --quiet, --silent
Quiet; do not write anything to standard output.
Exit immediately with zero status
if any match is found, even if an error was detected.

Flow Control and Return Values in a BashScript

I'm quite new to bash scripting and i've been working on a small bash file that can do a few things for me. First of all, i'm calling this from a C function using system() and i'd like the script to return a value (1 for error, 0 for OK). Is this possible?
int kinit() {
int err = system("/home/bluemoon/Desktop/GSSExample/kinitScript.sh");
}
Second, using Zenity, i managed to create a pop up window to insert user/password. Now, according to what the user does, multiple things should happen. If he closes the window or clicks "cancel", nothing should happen. If he clicks "OK", then i should check the input (for empty text boxes or something).
Assuming a correct input, i will use Expect to run a kinit program (it's a promt related with Kerberos) and log in. Now, if the password is correct, the prompt closes and the script should return 0. If it's not, the prompt will show something like "Kinit: user not found". I wanted to, in any case of error (closing window, clicking cancel or wrong credentials) return 1 in my script and return 0 on success.
#!/bin/bash
noText=""
ENTRY=`zenity --password --username`
case $? in
0)
USER=`echo $ENTRY | cut -d'|' -f1`
PW=`echo $ENTRY | cut -d'|' -f2`
if [ "$USER"!="$noText" -a "$PW"!="$noText" ]
then
/usr/bin/expect -c 'spawn kinit '`echo $USER`'; expect "Password for '`echo $USER`':" { send "'`echo $PW`'\r" }; interact'
fi
;;
1)
echo "Stop login.";;
-1)
echo "An unexpected error has occurred.";;
esac
My if isn't working properly, the expect command is always run. Cancelling or closing the Zenity window also always lead to case "0". I've also tried to return a variable but it says i can only return vars from inside functions?
Well, if anyone could give me some pointers, i'd appreciate it.
Dave
i'd like the script to return a value
Sure, just use exit in appropriate places
exit: exit [n]
Exit the shell.
Exits the shell with a status of N. If N is omitted, the exit status
is that of the last command executed.
My if isn't working properly, the expect command is always run.
if [ "$USER" != "$noText" -a "$PW" != "$noText" ]
# ^ ^ ^ ^
# | | | |
# \----- notice spaces ----/

Nagios bash script returns no output when executed through check_nrpe

My nagios bash script works fine from the client's command line.
When I execute the same script through check_nrpe from the nagios server it returns the following message "CHECK_NRPE: No output returned from daemon."
Seems like a command in the bash script is not being executed.
arrVars=(`/usr/bin/ipmitool sensor | grep "<System sensor>"`)
#echo "Hello World!!"
myOPString=""
<Process array and determine string to echo along with exit code>
echo $myOPString
if [[ $flag == "False" ]]; then
exit 1
else
exit 0
fi
"Hello World" shows up on the nagios monitoring screen if I uncomment the echo statement.
I am new to linux but seems like the nagios user isn't able to execute ipmitool
arrVars=(`/usr/bin/ipmitool sensor | grep "<System sensor>"`)
Check the output of the above, You can echo it and check for the values. If it still does not work use another script to be called by this to get the output and assign it to a variable
exit 1
This refers to the Severity , So you would have to define different conditions where the severity changes
Add this line to the sudoers
nagios ALL=(root) NOPASSWD: /usr/bin/ipmitool
Then use "sudo /usr/bin/ipmitool" in your script

Executing shell script with system() returns 256. What does that mean?

I've written a shell script to soft-restart HAProxy (reverse proxy). Executing the script from the shell works. But I want a daemon to execute the script. That doesn't work. system() returns 256. I have no clue what that might mean.
#!/bin/sh
# save previous state
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.old
mv /var/run/haproxy.pid /var/run/haproxy.pid.old
cp /tmp/haproxy.cfg.new /home/haproxy/haproxy.cfg
kill -TTOU $(cat /var/run/haproxy.pid.old)
if haproxy -p /var/run/haproxy.pid -f /home/haproxy/haproxy.cfg; then
kill -USR1 $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid.old
exit 1
else
kill -TTIN $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid
mv /var/run/haproxy.pid.old /var/run/haproxy.pid
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.err
mv /home/haproxy/haproxy.cfg.old /home/haproxy/haproxy.cfg
exit 0
fi
HAProxy is executed with user haproxy. My daemon has it's own user too. Both run with sudo.
Any hints?
According to this and that, Perl's system() returns exit values multiplied by 256. So it's actually exiting with 1. It seems this happens in C too.
Unless system returns -1 its return value is of the same format as the status value from the wait family of system calls (man 2 wait). There are macros to help you interpret this status:
man 3 wait
Lists these macros and what they tell you.
A code of 256 probably means that the system command cannot locate the binary to run it. Remember that it may not be calling bash and that it may not have paths setup. Try again with full paths to the binaries!
I have the same problem when call script that contains `kill' command in a daemon.
The daemon must have closed the stdout, stderr...
Use something like system("scrips.sh > /dev/null") should work.

Resources