diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-02-10 01:31:22 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-02-10 01:31:22 +0000 |
commit | 85848b86166719fe7164148608daa490bf9bfcdb (patch) | |
tree | 669ff49bb8253462e9b1fb75ac23bdbc1e344261 /lib/libutil/pty.c | |
parent | 92344befec63515228572bc04de856dfae3b3c00 (diff) |
Add the ptm device to pty(4). By opening /dev/ptm and using the PTMGET
ioctl(2), an unprivileged process may allocate a pty and have its owner
and mode set appropriately. This means that programs such as xterm and
screen no longer need to be setuid. Programs using the openpty()
function require zero changes and will "just work".
Designed by beck@ and deraadt@; changes by beck@ with cleanup (and
a rewrite of the vnode bits) by art@ and tweaks/bugfixes by me.
Tested by many.
Diffstat (limited to 'lib/libutil/pty.c')
-rw-r--r-- | lib/libutil/pty.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/lib/libutil/pty.c b/lib/libutil/pty.c index 743daf70491..a8fa7671537 100644 --- a/lib/libutil/pty.c +++ b/lib/libutil/pty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pty.c,v 1.10 2003/06/02 20:18:42 millert Exp $ */ +/* $OpenBSD: pty.c,v 1.11 2004/02/10 01:31:20 millert Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /* from: static char sccsid[] = "@(#)pty.c 8.1 (Berkeley) 6/4/93"; */ -static const char rcsid[] = "$Id: pty.c,v 1.10 2003/06/02 20:18:42 millert Exp $"; +static const char rcsid[] = "$Id: pty.c,v 1.11 2004/02/10 01:31:20 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/cdefs.h> @@ -44,6 +44,7 @@ static const char rcsid[] = "$Id: pty.c,v 1.10 2003/06/02 20:18:42 millert Exp $ #include <stdio.h> #include <string.h> #include <grp.h> +#include <sys/tty.h> #include "util.h" @@ -60,7 +61,41 @@ openpty(amaster, aslave, name, termp, winp) register const char *cp1, *cp2; register int master, slave, ttygid; struct group *gr; + struct ptmget ptm; + int fd; + /* Try to use /dev/ptm and the PTMGET ioctl to get a properly set up + * and owned pty/tty pair. If this fails, (because we might not have + * the ptm device, etc.) fall back to using the traditional method + * of walking through the pty entries in /dev for the moment, until + * there is less chance of people being seriously boned by running + * kernels without /dev/ptm in them. + */ + + fd = open(PATH_PTMDEV, O_RDWR, 0); + if (fd == -1) + goto walkit; + if ((ioctl(fd, PTMGET, &ptm) == -1)) { + close(fd); + goto walkit; + } + close(fd); + master = ptm.cfd; + slave = ptm.sfd; + if (name) { + /* + * Manual page says "at least 16 characters". + */ + strlcpy(name, ptm.sn, 16); + } + *amaster = master; + *aslave = slave; + if (termp) + (void) tcsetattr(slave, TCSAFLUSH, termp); + if (winp) + (void) ioctl(slave, TIOCSWINSZ, (char *)winp); + return (0); + walkit: if ((gr = getgrnam("tty")) != NULL) ttygid = gr->gr_gid; else |