File util-linux-su-change-owner-and-mode-for-pty.patch of Package util-linux.25286
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(-)
diff --git a/include/pty-session.h b/include/pty-session.h
index 0c9ccc6f0..09eff43fd 100644
--- a/include/pty-session.h
+++ b/include/pty-session.h
@@ -10,6 +10,7 @@
#include <termios.h>
#include <signal.h>
#include <sys/time.h>
+#include <sys/stat.h>
#include <sys/signalfd.h>
@@ -98,6 +99,7 @@ struct ul_pty_callbacks *ul_pty_get_callbacks(struct ul_pty *pty);
int ul_pty_is_running(struct ul_pty *pty);
int ul_pty_setup(struct ul_pty *pty);
void ul_pty_cleanup(struct ul_pty *pty);
+int ul_pty_chownmod_slave(struct ul_pty *pty, uid_t uid, gid_t gid, mode_t mode);
void ul_pty_init_slave(struct ul_pty *pty);
int ul_pty_proxy_master(struct ul_pty *pty);
diff --git a/lib/pty-session.c b/lib/pty-session.c
index f4bb0045a..8352f8c67 100644
--- a/lib/pty-session.c
+++ b/lib/pty-session.c
@@ -239,6 +239,15 @@ void ul_pty_cleanup(struct ul_pty *pty)
tcsetattr(STDIN_FILENO, TCSADRAIN, &rtt);
}
+int ul_pty_chownmod_slave(struct ul_pty *pty, uid_t uid, gid_t gid, mode_t mode)
+{
+ if (fchown(pty->slave, uid, gid))
+ return -errno;
+ if (fchmod(pty->slave, mode))
+ return -errno;
+ return 0;
+}
+
/* call me in child process */
void ul_pty_init_slave(struct ul_pty *pty)
{
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index ca49429df..afd0ea8ad 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -82,7 +82,6 @@ UL_DEBUG_DEFINE_MASKNAMES(su) = UL_DEBUG_EMPTY_MASKNAMES;
#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"
@@ -255,6 +254,26 @@ static void wait_for_child_cb(
{
wait_for_child((struct su_context *) data);
}
+
+static void chownmod_pty(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 (ul_pty_chownmod_slave(su->pty,
+ su->pwd->pw_uid,
+ gid, mode))
+ warn(_("change owner or mode for pseudo-terminal failed"));
+}
#endif
/* Log the fact that someone has run su to the user given by PW;
@@ -496,7 +515,6 @@ static void parent_setup_signals(struct su_context *su)
}
}
-
static void create_watching_parent(struct su_context *su)
{
int status;
@@ -1191,6 +1209,10 @@ int su_main(int argc, char **argv, int mode)
create_watching_parent(su);
/* Now we're in the child. */
+#ifdef USE_PTY
+ if (su->force_pty)
+ chownmod_pty(su);
+#endif
change_identity(su->pwd);
if (!su->same_session) {
/* note that on --pty we call setsid() in ul_pty_init_slave() */
--
2.36.1