10

TL;DR: What's the new right way to do a graphical sudo from a shell script?

Flailing:

I just upgraded from kubuntu 16.04 to 18.04 and I'm doing the normal triage.

kdesudo is gone in 18.04 (unmaintained).

I use it a lot in bash scripts with GUI i/o.

Some post said use kdesu - which seems weird. I seem to recall that it messes with the effective user or something like that.

That's not installed in my PATH.

I found it at

bigbird@sananda:~/pq$ ls -l /etc/alternatives/kdesu
rwxrwxrwx 1 root root 41 Aug 19 03:23 /etc/alternatives/kdesu -> 
/usr/lib/kde4/libexec/kdesu-distrib/kdesu

which still says kde4.

I tried sudo -A ls

and it said

bigbird@sananda:~$ sudo -A ls
sudo: no askpass program specified, try setting SUDO_ASKPASS

I went in a few circles looking at ksshaskpass and ssh-askpass, but both say they're not intended to be called directly.

I am not doing anything with ssh.

I need this for bash scripts that do almost everything as a normal user and then run one or two commands as root. These scripts are often launched from desktop icons where there is no terminal window open (and I don't need or want one.) They often use yad (like zenity or kdialog) to interface with the user.

Joe
  • 1,884
  • 1
    What about plain old sudo -H? – DK Bose Aug 20 '18 at 08:56
  • @DKBose - didn't know about that, but it doesn't solve the primary problem of getting a secure password from the user (me) when there's no terminal/CLI open. – Joe Aug 20 '18 at 09:38
  • I finally wrote a bash kdesudo() function that I use frequently. There was a link buried in the comments to the accepted answer. Here's the latest version: https://pastebin.com/GKtZa1px . – Joe Oct 16 '19 at 14:47

4 Answers4

6

As you have discovered, you can use the -A option with sudo, but you need a gui method of supplying the password to sudo.

You can write such a tool anyway you want, as long as it passes the password back to sudo on stdout. I use a simple solution which someone suggested to me a very long time ago, that uses kdialog, and like all simple solutions, it has remained my go to ever since.

So create yourself a simple kdialog script, such as this

    #!/bin/bash
    kdialog --password "Password required to proceed"

Now you use this with sudo like this

    #!/bin/bash
    export SUDO_ASKPASS=<path to your kdialog script>
    sudo -A foo

You can of course use any language you want to for your gui password provider if you don't have kde

EDIT: Solution to bypassing sudo passwd_tries

So that you can just ask for the password once only (as you want to do), you can capture the password in a variable within the script and pass that variable directly to the sudo command using the -S switch.

This has the advantage that it ignores the sudo passwd_tries rule, and still requires the interactive password input, so the password is not stored within the script.

PASSWD=$(kdialog --password "sudo password required")
echo $PASSWD | sudo -S foo

You can also do it directly on a line, if you do not need multiple sudo commands in the script, like this

echo $(kdialog --password "sudo password required") | sudo -S foo

And of course you can use your own kdialog script that we discussed earlier in place of using kdialog here, if you want a standard kdialog prompt in all your scripts.

The problem bypassing sudo's passwd_tries, from my POV, is that if you get the password wrong, your script will continue processing any commands after the sudo command, so if the sudo elevated command was critical to the script's success then you have problems.

The caveat is that the password from kdialog (or alternative such as zenity) is written on stdout, something I should have mentioned before, so anyone that has captured the PID's stdout would see your password. But then any hacker on your system would be doing a lot more than just that.

  • +1 I was wondering if it could be so simple. I just hope there aren't any new security issues. If I do it this way, I'll put it in /usr/local/bin. – Joe Aug 21 '18 at 05:56
  • 1
    No security issues as there are no passwords stored anywhere, kdialog writes the password directly to stdout which is piped to sudo's stdin. The permissions for sudo last for exactly that call. – nobody special Aug 21 '18 at 10:02
  • The dialog that kdialog presents has OK and Cancel buttons, but if I select Cancel, press Esc, or just click on the X in dialog frame, it still presents the dialog two more times. How do you tell it (or sudo), "No means no"? – Joe Aug 25 '18 at 04:06
  • sudo can be a demanding mistress lol, run the command sudo visudo -f /etc/sudoers and add the line Defaults passwd_tries=2 or whatever value you want it to be. Obviously if the default key already exists just edit the value to whatever you want it to be. – nobody special Aug 25 '18 at 12:57
  • BTW: as this seems to be working how you wanted, you could accept this as the answer for future people in the same position. – nobody special Aug 25 '18 at 13:31
  • I probably will accept this answer, but I've learned to wait awhile before jumping. I don't want to alter the retries globally. My fingers are as fat as anyone else's when I'm typing at the terminal. However, that may be the way to go if I don't see any better alternatives. I may also see if yad has any better luck than kdialog although it probably won't make a difference. – Joe Aug 26 '18 at 04:18
  • Had a thought about your sudo passwd_tries angst, and edited my answer with a solution that does not involve changing passwd_tries. Have a look and see if it solves your issues. – nobody special Aug 26 '18 at 12:16
  • That's almost perfect - except for the caveat. The problem is that anyone with almost no skills can run a command like ps -ef and possibly see the sudo password in the clear. Then, they can do almost anything. But for my personal use it seems fine. As for fall through, I tend to write long scripts with lots of error tests and messages because, if I screw up later, I want the script to explain to me what happened before I even start debugging. – Joe Aug 28 '18 at 04:57
  • So, for me, in a single user, desktop system, this solution is perfect. But I would not recommend using it on any server or other public facing system where security is an issue. For that, I'd stick with the original kdialog straight into the pipe variation. – Joe Aug 28 '18 at 05:05
  • I don't get the | tee /dev/tty. It works fine without it and just prints my password on the terminals. – Joe Aug 28 '18 at 05:32
  • I just tried three or four variations attempting to put kdialog inside a process substitution <(kdialog ...) to eliminate the variable, but I can't get it to work. Seems like there should be a way. That would eliminate the vulnerability. I might make that a separate question. – Joe Aug 28 '18 at 05:38
  • Got it! kdialog --password "sudo password required" | sudo -S -- ls /home/lost+found. Now I just have to add a few bells and whistles to make it pretty. It's almost the same as your second solution, only simpler because kdialog writes to stdout to start with. – Joe Aug 28 '18 at 06:06
  • Awesome, glad you worked it all out. I tend to write long documented bash scripts with test and reporting as best practice, if only so I know what I wrote them for in the first place. Scripting can be a complete pita to read at the best of times, even worse when you come back to them months later. – nobody special Aug 28 '18 at 11:18
  • haha, didn't realise I left tee in the answer (late night brain fart), was using that to test the output using a temp user account with a password I wasn't used to. I'll edit the answer to remove that so others don't use it, good catch. I find it best to test anything in a sandbox to avoid pollution from and to my own environment. – nobody special Aug 28 '18 at 11:51
  • Here are my "finished" versions of getpass for use with sudo -A https://pastebin.com/mrSUuJWr and kdesudo() which replaces its namesake with a bash function. https://pastebin.com/dAhYrXei. – Joe May 25 '19 at 05:27
  • I updated my kdesudo() function in May/2019. The new version is here: https://pastebin.com/GKtZa1px – Joe Oct 16 '19 at 14:40
3

Have you tried pkexec

pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY gedit
papampi
  • 407
  • 1
    Check this: https://askubuntu.com/questions/287845/how-to-configure-pkexec – papampi Aug 21 '18 at 10:08
  • @GunnarHjalmarsson Yes, I have, edited my original message as I set alias for it and forgot to post full command. – papampi Aug 21 '18 at 10:24
  • Can I ask why my answer is marked to get deleted? It brings up GUI dialogue box to enter password as its asked for. – papampi Aug 21 '18 at 13:30
  • I just read a bunch of links on this and my first impression is that it puts up a really ugly dialog and if you want to get rid of it, it's rocket science. It seems to be all about not running GUIs as root and I'm not doing that. I'm running relatively simple bash scripts that just need to be able to authorize individual commands without having access to a terminal. – Joe Aug 22 '18 at 02:40
  • I just tried this with one of my scripts. it works, but since the script had to issue more than one elevated command, I had to enter my password multiple times to do one thing. sudo and, by extension, its GUIs, had a timeout to avoid this problem. I do not want to elevate the whole script. – Joe Aug 25 '18 at 03:07
1

Not only kdesudo, but also gksu is also deprecated. These changes are at least mildly annoying. It seems the approach we are meant to take now is to utilize the admin:// prefix for example if you used to kdesudo gedit /etc/default/grub now you would instead gedit admin:///etc/default/grub This will definitely take some getting used to if I ever drop 16.04 for a "new and improved" version.

Another possible solution would be to simply launch the script in a terminal to begin with.

Source: https://www.linuxuprising.com/2018/04/gksu-removed-from-ubuntu-heres.html

Elder Geek
  • 36,023
  • 25
  • 98
  • 183
  • My first attempt to use this ran into roadblock. I have a script called from a GUI that just wants to run iptables. No place to put an admin://. – Joe Aug 25 '18 at 03:01
  • @Joe updated answer – Elder Geek Aug 25 '18 at 11:26
  • Thanks for the elaboration, but while that would work and you can even configure a command to open in a terminal in the KDE menu/desktop, it would be seriously ugly and distracting. @nobodyspecial 's answer is better than that for my purposes. It doesn't inspire confidence (from users) if it looks like you had to turn the whole system upside down just to get a task done. I will try the admin:// thing in other situations where it would work. I had not seen that before. – Joe Aug 26 '18 at 04:38
  • @Joe I'm glad you found a solution that you are comfortable with. If that answer is acceptable to you should accept it by clicking the check mark next to it. – Elder Geek Aug 27 '18 at 17:57
0

I just found some answers here.

The gist of it is:

For now, a workaround is to find where kdesu is installed on your system

which you can do with

ls -l /etc/alternatives/kdesu

and then add an alias for kdesudo to $HOME/.bashrc or, if you use it, to $HOME/.bash_aliases.

The alias is

## Resurect kdesudo - this will probably fail eventually
alias kdesudo='/usr/lib/kde4/libexec/kdesu-distrib/kdesu'

making sure to adjust the path to kdesu to the one you found in the step above.

This will not work for some programs under KDE because

The KDE developers are working on a polkit route to allow temporary elevated privileges for other applications as they have already done for Kate. -- GreyGeek

and when they do, they disable direct elevation because (if it works right) you don't need it any more. The program just asks for a password when it needs to do a privileged operation. It remains to be seen how that will work in a script.

Joe
  • 1,884