54

Let's say I have 2 user accounts user1 and user2. When I login as user1, and then switch to user2 using su, I can execute command-line programs, but GUI programs fail.

Example:

user1@laptop:~$ su - user2
user2@laptop:~$ leafpad ~/somefile.txt
No protocol specified
leafpad: Cannot open display: 

So how can I run a GUI application?

slm
  • 369,824
sashoalm
  • 5,820
  • One of the main reasons, I've found, that this fails is because $XAUTHORITY is still set to user1's ~/.Xauthority, which the program, I guess, will try to read, and it fails because that file typically has mode 0600 (-rw-------), meaning it's unavailable for reading by anyone in the "other" group, which includes user2. Meaning if you chmod o+r ~/.Xauthority (as user1), you will have hacked your way around this problem. I wrote a script that demonstrates this. – Braden Best Feb 03 '18 at 07:29

9 Answers9

56

su vs. su -

When becoming another user you generally want to use su - user2. The dash will force user2's .bash_profile to get sourced.

xhost

Additionally you'll need to grant users access to your display. This is governed by X. You can use the command xhost + to allow other users permission to display GUI's to user1's desktop.

NOTE: When running xhost + you'll want to run this while still in a shell that belongs to user1.

$DISPLAY

When you become user2 you may need to set the environment variable $DISPLAY.

$ export DISPLAY=:0.0
slm
  • 369,824
  • When should I execute xhost +user2? From user1 context or from user2 context? Both gave me an error - xhost: bad hostname "user2" when executing from user1, and No protocol specified xhost: unable to open display ":0" when executed from user2. – sashoalm Jan 10 '14 at 21:50
  • Btw I updated my question, you can remove the part about su - user2 now. – sashoalm Jan 10 '14 at 22:01
  • @satuon - OK, I'm going to leave it in the answer so that other people that may come across this Q&A in the future understand that that needs to be explicitly done. See updates. – slm Jan 11 '14 at 01:13
  • 1
    xhost +user2 still gives me this error - xhost: bad hostname "user2". I googled some, and it seems I need to do xhost +user2@laptop or xhost +user2@localhost, not sure which. Then it says xhost +user2@localhost being added to access control list. – sashoalm Jan 11 '14 at 10:10
  • 1
    But even after adding the user with xhost, and specifying export DISPLAY=:0.0, running leafpad still gives me No protocol specified leafpad: Cannot open display:, and fails to run. I found this link at http://www.linuxquestions.org/questions/linux-newbie-8/xlib-connection-to-0-0-refused-by-server-xlib-no-protocol-specified-152556/, which says that there are some magic cookies and xauth. Have you tested that those things work on your computer btw? Maybe something's different with my configuration? I'm on Debian+LXDE. – sashoalm Jan 11 '14 at 10:15
  • @satuon - instead of xhost +user2 try xhost + to allow anyone, just to see if that works. When in user1's desktop, in a shell type echo $DISPLAY, and confirm that they're on :0.0. – slm Jan 11 '14 at 12:58
  • 1
    Thanks, xhost + works, and nothing else seems to be needed (no need to set $DISPLAY). Can you update your answer, and I'll accept it? – sashoalm Jan 11 '14 at 22:27
  • @satuon - updated. – slm Jan 11 '14 at 22:40
  • @slm - is it possible to specify a user at all? Each time is gives a error about a bad hostname - I also tried various incantations of xhost +guest@127.0.0.1 and those didn't work (the output said the user had been added to the access control list though... - I am trying to test something under a different user without logging out :) xhost + does work on Fedora 21 though, and I ran xhost - after I finished as I think it returns it to normal. – Wilf Apr 21 '15 at 10:23
  • 7
    Oh, found something. On Fedora 21 running xhost gives a list in the format SI:localuser:USERNAME, so xhost SI:localuser:user2 should work. Oh and the display of the user can be found using w. – Wilf Apr 21 '15 at 11:01
  • Also described here – Wilf Apr 27 '15 at 12:38
  • I didn't understand the commands but it worked perfectly. :) – Vishal Kumar Sahu Mar 02 '17 at 08:47
  • 11
    xhost + will allow any user on any host that can connect to your x-server to access your screen. xhost +SI:localuser:user2 works for me on Debian. – robartsd Mar 17 '17 at 04:46
  • It's interesting to note that the only reason su ing to another user and executing a GUI program from that shell doesn't work is because $XAUTHORITY is set to user1's .Xauthority, which cannot normally be read by user2. Thus, running chmod o+r ~/.Xauthority as user1 and then running XAUTHORITY=/home/<user1>/.Xauthority DISPLAY=<display> <program> as user2 is a quick hack-y way to get around this. Even without any form of xhost +, from my experiments. Thus, I wrote a convenient script. – Braden Best Feb 03 '18 at 07:24
  • I am running Debian "testing" with Xfce. In the past, xhost + was enough, but now I realize that I must manually set and export $DISPLAY. Does anybody know why? – giusti Aug 20 '18 at 00:44
  • 3
    More xhost details and options (debian based solydX): This will allow any local user to access the display: xhost +local:

    From the man page: "The local family specifies all the local connections at once. However, the server interpreted address "si:localuser:username" can be used to specify a single local user"

    So this worked for me: xhost +si:localuser:[username]

    – Peter Kay Jun 06 '20 at 15:04
17

You could use X11 forwarding:

ssh -XY otheruser@localhost your-gui-program-name-here
Michael F
  • 281
11

You need to share the authentication token from the user1 (assuming ~is home of user1):

cat ~/.Xauthority | sudo -u user2 -i tee .Xauthority > /dev/null
10

You can start app from another user. I will start the gimp app from user2, while being logged in (GUI) with user 1:

$ xhost +
$ sudo su user2

(enter pass)

$ gimp

Enjoy :)

4

You may try the sux command:

sux user2

sux will handle the $DISPLAY stuff for you. You may need to install it with:

sudo apt-get install sux

under Debian/Ubuntu.

phil
  • 141
  • 4
    sux is no longer shipped by Debian or Ubuntu. The best alternative I could find is adding xhost SI:localuser:root (or whatever user) to ~/.xprofile to allow it permanently or to use runuser – stefanct May 21 '16 at 21:34
  • Up to and including Debian Stretch, there was gksu / gksudo alternative that worked fine. While still in Sid, it is removed in Buster for security issues. – Matija Nalis Sep 07 '19 at 22:27
3

As alternative to sux, to safely run graphical command (firefox-esr in example below) as $AUTHUSER (guest in example below):

AUTHUSER=guest
AUTHSTRING=SI:localuser:${AUTHUSER}
xhost +${AUTHSTRING} > /dev/null
SUDO_ASKPASS=/usr/bin/ssh-askpass
export SUDO_ASKPASS
sudo -k --askpass -u ${AUTHUSER} /usr/bin/firefox-esr
xhost -${AUTHSTRING} > /dev/null
sudo -K

the code does:

  1. gives the guest user access to your current user $DISPLAY via xhost +SI:localuser:guest
  2. uses ssh-askpass to graphically ask you for password (of course, you could use sudoers(5) NOPASSWD: to avoid this, if your security policy thinks it is ok. Or you could use other askpass programs, or specify them in config files (see sudo(8) for details on --askpass)
  3. if the password is ok (and you have permissions in sudoers(5)) it runs the command /usr/bin/firefox-esr as another user (guest)
  4. after the program completes, permissions to other user (guest) to access your $DISPLAY are revoked via xhost -SI:localuser:guest
  5. finally, sudo -K removes cached password, so next invocation of ssh-askpass will ask you for password again (instead of using cached password)

    while it is little more work than what gksu(8) or sux(8) did, it can be scripted, and it is much more secure than:

    • xhost + (any user will have access to your graphical display as long as it is in effect)
    • readable ~/.xauth by other users (indefinite access by that user to your display)
    • what gksu/sux did (temporary copy of ~/.Xauthority, which allowed specified user to copy your MIT-MAGIC-COOKIE-1 and continue using your display even after gksu/sux finished (as long as you did not shutdown machine or logged out of display - screensavers, hibernate etc did not change the magic cookie).

as it will allow only one local user access to your display, and then only as long as the command runs (when command finishes, $AUTHUSER will no longer be able to access your display in any way).

Another safe alternative is ssh -X (without -Y which actually makes you less secure! see ForwardX11Trusted in ssh_config(5) for details), as is easier to use if you are not scripting it, but it induces additinal overhead (eg. it is slower) and some programs might not work correctly without unsafe -Y.

Matija Nalis
  • 3,111
  • 1
  • 14
  • 27
3

You can use pkexec, from man pkexec:

DESCRIPTION
pkexec allows an authorized user to execute PROGRAM as another user. If username is not specified, then the program will be executed as the administrative super user, root.

First you need to give to that user the permission with xhost, to use the GUI.

To add an user permanently you can add the following xhost command to /etc/bash.bashrc (system wide) or locally in ~/.bashrc. On debian.

You can use this script to launch leafpad as user2:

#!/bin/sh

xhost SI:localuser:user2 pkexec --user user2 env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY leafpad

Scorpion
  • 757
  • you can also add access to $XAUTHORITY file

    ~ > chgrp developer $XAUTHORITY ~ > chmod g+r $XAUTHORITY If both users are in same group developer

    – Bogdan Mart Aug 15 '23 at 05:56
3

Most solutions provided here don't integrate with Wayland and PulseAudio.

I wrote ego (Alter Ego), which automatically handles xhost and Wayland and PulseAudio socket sharing: https://github.com/intgr/ego

So you just run ego leafpad or ego -u user2 leafpad

If you run into problems, please open an issue on GitHub. I may be the only user of it, so it hasn't gotten much testing yet.

intgr
  • 227
-2

You need to load installation UI as user2.

Try to following this:

Login as root:

sudo su

Test the x server:

xclock

If you can see a clock running, that's good to go, now try run this:

xhost

The result should like this:

xhost SI:localuser:tri
# tri is my user name

Now let user2 access xhost

xhost +SI:localuser:user2

now try to login again to user2 and try to open any of GUI program.

Tri
  • 107
  • 4
  • 1
    (1) There is nothing in this question that requires running as root, or where running as root is beneficial. (1b) If anything, running as root may just confuse matters. (2) There’s rarely (if ever) any reason to use sudo su.  Use sudo or su; pick one. (3) The question is written in terms of user1 and user2.  Please write your answer in terms of user1 and user2.  (Do or do not; there is no tri.) (4) Your answer would be better if it included an explanation of SI:localuser. … … … … … … … Please do not respond in comments; [edit] your answer to make it clearer and more complete. – Scott - Слава Україні Jun 26 '19 at 16:27