su: (pty) change owner and mode for pty
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>
This commit is contained in:
parent
726ffb4a26
commit
17d5b26436
|
@ -10,6 +10,7 @@
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <sys/signalfd.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_is_running(struct ul_pty *pty);
|
||||||
int ul_pty_setup(struct ul_pty *pty);
|
int ul_pty_setup(struct ul_pty *pty);
|
||||||
void ul_pty_cleanup(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);
|
void ul_pty_init_slave(struct ul_pty *pty);
|
||||||
int ul_pty_proxy_master(struct ul_pty *pty);
|
int ul_pty_proxy_master(struct ul_pty *pty);
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,15 @@ void ul_pty_cleanup(struct ul_pty *pty)
|
||||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &rtt);
|
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 */
|
/* call me in child process */
|
||||||
void ul_pty_init_slave(struct ul_pty *pty)
|
void ul_pty_init_slave(struct ul_pty *pty)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 DBG(m, x) __UL_DBG(su, SU_DEBUG_, m, x)
|
||||||
#define ON_DBG(m, x) __UL_DBG_CALL(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 - */
|
/* name of the pam configuration files. separate configs for su and su - */
|
||||||
#define PAM_SRVNAME_SU "su"
|
#define PAM_SRVNAME_SU "su"
|
||||||
#define PAM_SRVNAME_SU_L "su-l"
|
#define PAM_SRVNAME_SU_L "su-l"
|
||||||
|
@ -255,6 +254,26 @@ static void wait_for_child_cb(
|
||||||
{
|
{
|
||||||
wait_for_child((struct su_context *) data);
|
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
|
#endif
|
||||||
|
|
||||||
/* Log the fact that someone has run su to the user given by PW;
|
/* 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)
|
static void create_watching_parent(struct su_context *su)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
@ -1191,6 +1209,10 @@ int su_main(int argc, char **argv, int mode)
|
||||||
create_watching_parent(su);
|
create_watching_parent(su);
|
||||||
/* Now we're in the child. */
|
/* Now we're in the child. */
|
||||||
|
|
||||||
|
#ifdef USE_PTY
|
||||||
|
if (su->force_pty)
|
||||||
|
chownmod_pty(su);
|
||||||
|
#endif
|
||||||
change_identity(su->pwd);
|
change_identity(su->pwd);
|
||||||
if (!su->same_session) {
|
if (!su->same_session) {
|
||||||
/* note that on --pty we call setsid() in ul_pty_init_slave() */
|
/* note that on --pty we call setsid() in ul_pty_init_slave() */
|
||||||
|
|
Loading…
Reference in New Issue