diff -urN Linux-PAM-1.5.0/modules/pam_xauth/pam_xauth.c Linux-PAM-1.5.0.xauth/modules/pam_xauth/pam_xauth.c --- Linux-PAM-1.5.0/modules/pam_xauth/pam_xauth.c 2020-11-10 16:46:13.000000000 +0100 +++ Linux-PAM-1.5.0.xauth/modules/pam_xauth/pam_xauth.c 2020-11-19 11:50:54.176925556 +0100 @@ -355,11 +355,13 @@ char *cookiefile = NULL, *xauthority = NULL, *cookie = NULL, *display = NULL, *tmp = NULL, *xauthlocalhostname = NULL; - const char *user, *xauth = NULL; + const char *user, *xauth = NULL, *login_name; struct passwd *tpwd, *rpwd; int fd, i, debug = 0; int retval = PAM_SUCCESS; - uid_t systemuser = 499, targetuser = 0; + uid_t systemuser = 499, targetuser = 0, uid; + gid_t gid; + struct stat st; /* Parse arguments. We don't understand many, so no sense in breaking * this into a separate function. */ @@ -429,7 +431,16 @@ retval = PAM_SESSION_ERR; goto cleanup; } - rpwd = pam_modutil_getpwuid(pamh, getuid()); + + login_name = pam_modutil_getlogin(pamh); + if (login_name == NULL) { + login_name = ""; + } + if (*login_name) + rpwd = pam_modutil_getpwnam(pamh, login_name); + else + rpwd = pam_modutil_getpwuid(pamh, getuid()); + if (rpwd == NULL) { pam_syslog(pamh, LOG_ERR, "error determining invoking user's name"); @@ -518,18 +529,26 @@ cookiefile); } + /* Get owner and group of the cookiefile */ + uid = getuid(); + gid = getgid(); + if (stat(cookiefile, &st) == 0) { + uid = st.st_uid; + gid = st.st_gid; + } + /* Read the user's .Xauthority file. Because the current UID is * the original user's UID, this will only fail if something has * gone wrong, or we have no cookies. */ if (debug) { pam_syslog(pamh, LOG_DEBUG, - "running \"%s %s %s %s %s\" as %lu/%lu", - xauth, "-f", cookiefile, "nlist", display, - (unsigned long) getuid(), (unsigned long) getgid()); + "running \"%s %s %s %s %s %s\" as %lu/%lu", + xauth, "-i", "-f", cookiefile, "nlist", display, + (unsigned long) uid, (unsigned long) gid); } if (run_coprocess(pamh, NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, "nlist", display, + uid, gid, + xauth, "-i", "-f", cookiefile, "nlist", display, NULL) == 0) { #ifdef WITH_SELINUX char *context_raw = NULL; @@ -583,12 +602,12 @@ cookiefile, "nlist", t, - (unsigned long) getuid(), - (unsigned long) getgid()); + (unsigned long) uid, + (unsigned long) gid); } run_coprocess(pamh, NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, + uid, gid, + xauth, "-i", "-f", cookiefile, "nlist", t, NULL); } free(t); @@ -673,13 +692,17 @@ goto cleanup; } + if (debug) { + pam_syslog(pamh, LOG_DEBUG, "set environment variable '%s'", + xauthority); + } /* Set the new variable in the environment. */ if (pam_putenv (pamh, xauthority) != PAM_SUCCESS) pam_syslog(pamh, LOG_ERR, "can't set environment variable '%s'", xauthority); putenv (xauthority); /* The environment owns this string now. */ - xauthority = NULL; /* Don't free environment variables. */ + /* Don't free environment variables nor set them to NULL. */ /* set $DISPLAY in pam handle to make su - work */ {