34

(Originally posted on Stack Overflow). They suggested I try here instead. Here's the original post:

See title. I want a command that lets me query sudo. Ideally, it would return success if I still have sudo and false if sudo has expired. Getting the time left might also be useful (although if I was concerned I could just do sudo -v to revalidate.) Oh and it shouldn't have to ask for a password.

The closest thing I've found is sudo -n true, but the -n option is only present on my Centos 5 machine at work. -n fails if it has to ask for a password. Is there any other way to get this functionality? Assume I don't actually have root on all the machines I work with, so I can't install new versions of sudo to my liking.

For what it's worth I'm doing this so I can get my prompt to indicate sudo status. I like knowing which terminals are actively sudo-able. I also have a prompt that changes colors when I'm root, but I don't use root very often so that's of limited use.

0

11 Answers 11

13

The -n option is available in newer versions of sudo, but as you stated that's not an option. There's no real way to do what you're looking for short of just trying sudo and seeing if it comes back with a prompt for a password. If your concern is you want a visual indication, why not start do sudo /bin/bash to start a root bash session? Note that this is insecure, but it's also somewhat insecure if someone realizes your prompt changes on sudo.

6
  • 1
    +1 for the security ramifications of a visual indicator! Oct 4, 2010 at 19:50
  • That part hadn't occurred to me. What I'm hoping the indicator does is remind me to run sudo -K, instead of forgetting I left sudo active and leaving some potentially dangerous terminals open. Not that I often forget to lock my screen, but I like the extra insurance.
    – valadil
    Oct 4, 2010 at 20:11
  • At the moment I'm leaning toward checking sudo -V, and if it's sufficiently new enough to have -n, checking -n to get the notification. Seems like it shouldn't break anything anywhere.
    – valadil
    Oct 4, 2010 at 20:12
  • @valadil: It occurs to me that a subtle indicator wouldn't introduce too much security risk. Turn on underlining for the username in the prompt, for example. Oct 4, 2010 at 21:05
  • 1
    @Dennis: Exactly. I wasn't going to change my prompt into "OMG_YOU_HAVE_SUDO_NOW!_user@host" or something like that. I'd probably just change the color a little. I don't expect anybody to know what that means unless they sit down and get intimate with my .bashrc.
    – valadil
    Oct 4, 2010 at 23:42
32

I know this is a really old question but here is I did in a script today. Assuming that being sudo means being able to run any command as sudo (or, at least, uptime)

CAN_I_RUN_SUDO=$(sudo -n uptime 2>&1 | grep "load" | wc -l)
if [ ${CAN_I_RUN_SUDO} -gt 0 ]
then
    echo "I can run the sudo command"
else
    echo "I can't run the Sudo command"
fi

However, if your user has restrictions in the visudo, this check will not be enough, e.g., if your user can only use the make command. Try running some command that you know will work.

You may add the filter grep -v Sorry, e.g.:

$(sudo -n uptime 2>&1 | grep "load" | grep -v Sorry | wc -l)

for avoiding those false positives.

1
  • For an user that does have none configuration through in sudoers - therefore is impossible use sudo - the execution of sudo -n <command> always prints in the terminal the sudo: a password is required message. So be careful with this approach - therefore $(sudo -n uptime 2>&1 | grep "load" | wc -l) always is going to return 0. This approach is really valuable if user can use sudo and the timeout is still valid - it returns 1 Feb 24, 2022 at 20:52
3

To simplify the answer given by @wags007

if sudo -n true
then
  sudo id
else
  echo "sorry, but did not want to bother you"
fi

However, if in your https://www.sudo.ws/man/1.8.15/sudoers.man.html configuration you have defaults mail_badpass there will be a mail sent for every test that results in false (would have prompted). To avoid such nuisance change that part of your sudoers file to

Defaults       mail_badpass
Defaults!      /bin/true !mail_badpass

As a result security alert mails are send for all commands except /bin/true. Well yes, somebody could now try to brute force a password by calling sudo true an unlimited number of times without any security alert mail being sent.

Note: Always use visudo instead of your favorite editor to edit the sudoers file. Failing to do so you risk being locked out.

1

The command below will show a colored indication that you have sudo granted, so you remember to do a sudo -k before going away from the machine. It is useful also on non colored terminals.

As we can have sudo active and inactive on different terminal sessions, I created this that you can put at the end of your ~/.bashrc

function FUNCpromptCommand () { 
    sudo -n uptime 2>/dev/null 1>/dev/null
  local bSudoOn=`if(($?==0));then echo true; else echo false; fi`

    history -a; # append to history at each command issued!!!
    local width=`tput cols`;
    local half=$((width/2))
    local dt="[EndAt:`date +"%Y/%m/%d-%H:%M:%S.%N"`]";
  if $bSudoOn; then dt="!!!SUDO!!!$dt"; fi
    local sizeDtHalf=$((${#dt}/2))
    #printf "%-${width}s" $dt |sed 's" "="g'; 
    echo
    output=`printf "%*s%*s" $((half+sizeDtHalf)) "$dt" $((half-sizeDtHalf)) "" |sed 's" "="g';`

    local colorLightRed="\e[1;31m"
  local colorNoColor="\e[0m"
    if $bSudoOn; then
        echo -e "${colorLightRed}${output}${colorNoColor}"
    else
        echo -e "${output}"
    fi
}
export PROMPT_COMMAND=FUNCpromptCommand

At terminal type bash to test it. It will also add a whole line each time you execute a command, that has the information of the time the last command ended, so you can go lunch and know when the last command ended :).

You can play with this code to fit your needs. There is the PS1 variable also (that is the actual small prompt single line), but I think it is better to not mess with it.

PS.: for OS-X, look for the comment below by @nwinkler.

5
  • Checking the exit code of sudo -n does not seem to work on OS X. See my question here: superuser.com/questions/902826/…
    – nwinkler
    Apr 17, 2015 at 15:38
  • well, the test I propose is sudo -n, do you believe there could have any other test that could be used to determine if user has sudo access active? or maybe OS-X requires some update? I never used OS-X btw. Apr 17, 2015 at 23:05
  • 2
    I'm using the latest version of OS X. It's possible that sudo -n on BSD (which OS X is based on) has a different behavior than the GNU version. I just added my comment to let people know that this version of the check does not seem to work on OS X. I have used a check from another answer (sudo -n uptime 2>&1|grep "load"|wc -l), and this seems to work fine on OS X. It's not as elegant, but it works.
    – nwinkler
    Apr 20, 2015 at 6:07
  • 1
    @nwinkler oh, so it actually depends on the output it generates (not the return value), interesting workaround Apr 20, 2015 at 22:24
  • @nwinkler but it is as near as possible. Or even better because sudo -n becomes buggy in sudo -V 1.7.9 Jun 11, 2015 at 22:08
0

According to the sudo manual, the sudo session is determined according to the time stamp file (/usr/lib/sudo/<username>), so you may be able to figure out how much time is left by checking the date/time of the time stamp file. However, in my system, the time stamp file is in fact a directory, and there are three files with cryptic content in them (and also some weird time stamps, but /usr/lib/sudo/<username> seemed to have a timestamp that coincided with the time I gave sudo my password. I think /usr/lib/sudo/<username>/0 has the time stamp of the most recent sudo execution.

2
  • 1
    On my system, the timestamp files are in a directory which can't be read without using sudo, which prompts for a password and thus wouldn't work for the OP's needs. Oct 4, 2010 at 21:04
  • Good point. I didn't check ownership of these files. You are right, it would be useless.
    – Dysaster
    Oct 4, 2010 at 21:07
0

Warning

Acording to Bugzilla sudo Bug ID=590 the call to sudo -n true 2&>/dev/null ; echo $? will become buggy around sudo -V 1.7.10

Read Bugzilla [here](http://bugzilla.sudo.ws/show_bug.cgi?id=590"Bug ID=590")

0

At least on sudo 1.8.21p2, this approach works fine:

if sudo -vn 2> /dev/null; then
    echo "You have an active sudo session"
fi
0

This is probably extreme overkill by most people's standard, but here is the (posixly correct) function I use to check if sudo is unlocked (the function will not waste its time if the user running it is root, as there is no need to unlock sudo):

#!/bin/sh

_unlock_sudo() {
    if [ "$USER" != 'root' ]; then
        if ! sudo -n -- true 2>/dev/null; then
            printf '\n'
            printf 'Enter password for sudo user "%s":\n' "$USER"
            while ! sudo -- true; do
                printf '\n'
                while true; do
                    printf 'Slow your roll. Try to enter password again? [Y/n]: '
                    read -r answer
                    case "$answer" in
                        ''|y|Y|yes|Yes|YES)
                            printf '\n'
                            printf 'Enter password for sudo user "%s":\n' "$USER"
                            break
                            ;;
                        n|N|no|No|NO)
                            printf '\n'
                            printf 'OK. Exiting...\n'
                            exit 1
                            ;;
                        *)
                            printf 'Please enter a valid option...\n'
                            printf '\n'
                            ;;
                    esac
                done
            done
        fi
    fi
}

_unlock_sudo
0

Very old question but I have a solution that does not require the -s flag, and does not require temperamental string operations.

A good solution might be to exploit the fact that an unauthenticated sudo call hangs for a long time.

sudo date will return pretty much instantly if authenticated, but will hang if not.

The timeout command is placed before another command to limit how long it takes to execute, and exits with code 124 if it cuts the execution of the inner command short. You can check the exit code of the last command with echo $?

With that in mind...

timeout .1s sudo date
EXITCODE=$?

Now test if $EXITCODE is 127 or not and you have your answer :)

-1

simple answer ...

sudo echo
isSudo=$?
if [[ "$isSudo" -ne 0 ]]; then
  echo "This script must be run by root or a sudo'er"
  echo
  exit 1
fi

# do stuff

exit 0
1
  • This will prompt for a password, if the user doesn't already have an active sudo session
    – Slizzered
    Apr 20, 2015 at 23:15
-2

How about the man page

man sudo

List your available commands:

sudo -l

sudo itself has no time or date limits... see:

man sudo
man sudoers
3
  • sudo -l gives me a password prompt. I need it to tell me I have no active sudo session.
    – valadil
    Oct 4, 2010 at 19:36
  • sudo status times out, but you're correct if you mean that it doesn't have a schedule feature. Oct 4, 2010 at 19:53
  • Yes - it times out - but no schedule. Oct 7, 2010 at 22:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .