3

I just noticed something peculiar about how sudo handles the .Xauthority file:

sudo xauth add $(xauth list | tail -1)

user@server: sudo xauth info
Authority file:       /root/.xauthYZ21Nt
File new:             no
File locked:          no
Number of entries:    1
Changes honored:      yes
Changes made:         no
Current input:        (argv):1

user@server:  sudo xauth info
Authority file:       /root/.xauth3BFy5d
File new:             no
File locked:          no
Number of entries:    1
Changes honored:      yes
Changes made:         no
Current input:        (argv):1

user@server:  sudo xauth list
server/unix:10  MIT-MAGIC-COOKIE-1  c922ab48defdf43b1092dffb86c06eed

user@server: sudo ls -la /root | grep auth
-rw-r--r--  1 root root    0 Nov  9 14:40 .Xauthority
-rw-------  1 root root   57 Nov  9 15:23 .xauthsrxzxl

user@server:  pkexec xauth info
Authority file:       /root/.Xauthority
File new:             no
File locked:          no
Number of entries:    0
Changes honored:      yes
Changes made:         no
Current input:        (argv):1

So, $XAUTHORITY value is different in every new sudo, and it points to a temporary file which disappears when sudo quits. Because of this, the last command (which uses pkexec instead of sudo and expects it to be in /root/.Xauthority) fails to see the cookie. For instance, sudo gedit runs fine, but pkexec env DISPLAY=$DISPLAY gedit fails.

Why is it done in such a complicated way, where is the data stored, and more importantly, how can I access .Xauthority data with pkexec?

Dmitry Grigoryev
  • 7,123
  • 2
  • 23
  • 62

5 Answers5

4

When an X server starts with -auth option it creates a file with MIT-MAGIC-COOKIE-1 (password), and only users who know this password can display their windows in X window system.

There can be more then one MIT-MAGIC-COOKIE-1 (net login, ssh -X, ...), but I think in your case, if you check these files - they will have the exact same content (cmp /root/.xauth1 /root/.xauth2).

However if you start a different X server, and use sudo (or su), the new password should be different.

So the reason for different files is because sudo didn't know which display is used by other instances and it gets the only passwords it needed (and creates new file to store it).

AdminBee
  • 21,637
  • 21
  • 47
  • 71
2

The xauth cookie is stored in that temporary file (~/.xauthXXXX) which is removed when sudo returns (e.g. when the sudo xauth info command has finished).

I suggest you have a look at the source code of the pam_xauth module:

#define XAUTHTMP ".xauthXXXXXX"
...
int
pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
                     int argc, const char **argv)
{
...

                /* Generate the environment variable
                 * "XAUTHORITY=<homedir>/filename". */
                if (asprintf(&xauthority, "%s=%s/%s",
                             XAUTHENV, tpwd->pw_dir, XAUTHTMP) < 0) {
...
                fd = mkstemp(xauthority + sizeof(XAUTHENV));
...
                cookiefile = strdup(xauthority + sizeof(XAUTHENV));

                /* Save the filename. */
                if (pam_set_data(pamh, DATANAME, cookiefile, cleanup) != PAM_SUCCESS) {
...
int
pam_sm_close_session (pam_handle_t *pamh, int flags UNUSED,
                      int argc, const char **argv)
{
...
        if (pam_get_data(pamh, DATANAME, &data) != PAM_SUCCESS)
                return PAM_SUCCESS;
        cookiefile = data;
...
        if (unlink(cookiefile) == -1 && errno != ENOENT)
          pam_syslog(pamh, LOG_WARNING, "Couldn't remove `%s': %m", cookiefile);

As to pkexec, I don't think you're supposed to run X11 apps with pkexec. It's bad enough that you can run them with sudo ;-)

  • Thanks. Sure, the moment I will be able to run e.g. `gparted` using a GVfs admin scheme, I'll stop running it as `root`, but for now there is no other way AFAIK. – Dmitry Grigoryev Nov 11 '21 at 16:33
1

It all seems to be clear now, thanks @user499944. In short:

  • the temporary .xauthXXXXXX files are created by pam_xauth.

  • they are only created if $DISPLAY is set, which is the case with sudo but not with pkexec. Running pkexed env DISPLAY=$DISPLAY command achieves nothing, because $DISPLAY is only set after the authentication completes. This is revealed in the system logs:

# after pkexec env DISPLAY=$DISPLAY xauth info
Nov 11 18:01:41 server pkexec[11650]: pam_xauth(polkit-1:session): user has no DISPLAY, doing nothing
Nov 11 18:01:41 server pkexec[11650]: user: Executing command [USER=root] [TTY=/dev/pts/3] [CWD=/home/user] [COMMAND=/usr/bin/env DISPLAY=localhost:10.0 xauth info]

# after sudo xauth info
Nov 11 18:04:12 server sudo[11666]: user : TTY=pts/3 ; PWD=/home/user ; USER=root ; COMMAND=/usr/bin/xauth info
# no message from pam_xauth about missing DISPLAY
Dmitry Grigoryev
  • 7,123
  • 2
  • 23
  • 62
0

I found an ugly workaround which allows pkexec to run correctly by copying the cookie twice:

sudo xauth -f /root/.Xauthority add $(xauth list $DISPLAY) # copy the cookie for pkexec

sudo gedit # works thanks to what sudo is doing
pkexec env DISPLAY=$DISPLAY gedit # works thanks to the first line above

# Check out that I now have two files
sudo ls -la /root | grep auth
-rw-------  1 root root   57 Nov 11 11:22 .xauth0XYhX3
-rw-------  1 root root   57 Nov 11 11:17 .Xauthority

I'm still looking for the answer to the original question (where the xauth data from the temporary files is actually stored?), which would hopefully allow me to use the same cookie for both sudo and pkexec commands.

Dmitry Grigoryev
  • 7,123
  • 2
  • 23
  • 62
0

To answer the part about why pam_xauth stores each cookie in a separate file, there are two reasons:

  • to allow only that one display to be accessed, rather than all the user's current displays, and
  • to allow that access to be removed at the end of the sudo session, by deleting the file.

In summary: scope and lifetime.

Toby Speight
  • 8,460
  • 3
  • 26
  • 50