File pam-xauth_ownership.patch of Package pam

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 */
 		{
openSUSE Build Service is sponsored by