File util-linux-su-change-owner-and-mode-for-pty.patch of Package python-libmount.32955

From 17d5b264367debb745b678fcafacbaa938b29455 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 23 Feb 2021 11:52:45 +0100
Subject: [PATCH] su: (pty) change owner and mode for pty
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The current situation:

 # su --pty - kzak
 $ ll $(tty)
 crw--w---- 1 root tty 136, 9 Feb 23 11:53 /dev/pts/9
 $ mesg
 mesg: cannot open /dev/pts/9: Permission denied

the pseudo-terminal is still owned by the original user.

New version:

 # su --pty - kzak
 # ll $(tty)
 crw--w---- 1 kzak tty 136, 9 Feb 23 11:56 /dev/pts/9
 # mesg
 is y

The patch follows login(1) to change the pty owner and group. It
follows "TTYPERM" and "TTYGROUP" from login.defs (or econf lib).

Signed-off-by: Karel Zak <kzak@redhat.com>
---
 include/pty-session.h   |  2 ++
 lib/pty-session.c       |  9 +++++++++
 login-utils/su-common.c | 26 ++++++++++++++++++++++++--
 3 files changed, 35 insertions(+), 2 deletions(-)

Index: util-linux-2.33.2/login-utils/su-common.c
===================================================================
--- util-linux-2.33.2.orig/login-utils/su-common.c
+++ util-linux-2.33.2/login-utils/su-common.c
@@ -34,6 +34,7 @@
 #endif
 #include <signal.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
 #include <syslog.h>
 #include <utmpx.h>
 
@@ -82,7 +83,6 @@ UL_DEBUG_DEFINE_MASKNAMES(su) = UL_DEBUG
 #define DBG(m, x)       __UL_DBG(su, SU_DEBUG_, m, x)
 #define ON_DBG(m, x)    __UL_DBG_CALL(su, SU_DEBUG_, m, x)
 
-
 /* name of the pam configuration files. separate configs for su and su -  */
 #define PAM_SRVNAME_SU "su"
 #define PAM_SRVNAME_SU_L "su-l"
@@ -582,6 +582,36 @@ static void pty_proxy_master(struct su_c
 	su->pty_sigfd = -1;
 	DBG(PTY, ul_debug("poll() done [signal=%d, rc=%d]", caught_signal, rc));
 }
+
+/* Needed for chownmod_pty, backported from pty-session.c that does not exist yet. */
+static int pty_chownmod_slave(struct su_context *su, uid_t uid, gid_t gid, mode_t mode)
+{
+	if (fchown(su->pty_slave, uid, gid))
+		return -errno;
+	if (fchmod(su->pty_slave, mode))
+		return -errno;
+	return 0;
+}
+
+static void pty_chownmod(struct su_context *su)
+{
+	gid_t gid = su->pwd->pw_gid;
+	mode_t mode = (mode_t) getlogindefs_num("TTYPERM", TTY_MODE);
+	const char *grname = getlogindefs_str("TTYGROUP", TTYGRPNAME);
+
+	if (grname && *grname) {
+		struct group *gr = getgrnam(grname);
+		if (gr)	/* group by name */
+			gid = gr->gr_gid;
+		else	/* group by ID */
+			gid = (gid_t) getlogindefs_num("TTYGROUP", gid);
+	}
+
+	if (pty_chownmod_slave(su,
+			       su->pwd->pw_uid,
+			       gid, mode))
+		warn(_("change owner or mode for pseudo-terminal failed"));
+}
 #endif /* USE_PTY */
 
 
@@ -824,7 +854,6 @@ static void parent_setup_signals(struct
 	}
 }
 
-
 static void create_watching_parent(struct su_context *su)
 {
 	int status;
@@ -1625,6 +1654,10 @@ int su_main(int argc, char **argv, int m
 	create_watching_parent(su);
 	/* Now we're in the child.  */
 
+#ifdef USE_PTY
+	if (su->pty)
+		pty_chownmod(su);
+#endif
 	change_identity(su->pwd);
 	if (!su->same_session || su->pty) {
 		DBG(MISC, ul_debug("call setsid()"));
openSUSE Build Service is sponsored by