$OpenBSD: patch-main_c,v 1.2 2002/11/21 05:41:14 pvalchev Exp $ --- main.c.orig Wed Nov 20 00:27:51 2002 +++ main.c Wed Nov 20 01:02:33 2002 @@ -142,9 +142,16 @@ static Bool IsPts = False; #define WTMP #endif +#ifdef CSRG_BASED +#define USE_POSIX_TERMIOS +#endif + #include #include +#ifdef USE_POSIX_TERMIOS +#include +#else #ifdef USE_TERMIOS #include /* this hacked termios support only works on SYSV */ @@ -159,10 +166,12 @@ static Bool IsPts = False; #include #endif /* SYSV */ #endif /* USE_TERMIOS else */ +#endif /* USE_POSIX_TERMIOS */ #ifdef SVR4 #undef TIOCSLTC /* defined, but not useable */ #endif +#define USE_TERMCAP_ENVVARS /* every one uses this except SYSV maybe */ #if defined(__sgi) && OSMAJORVERSION >= 5 #undef TIOCLSET /* defined, but not useable */ @@ -225,7 +234,9 @@ static Bool IsPts = False; #endif #else /* } !SYSV { */ /* BSD systems */ #ifndef linux +#ifndef USE_POSIX_TERMIOS #include +#endif /* USE_POSIX_TERMIOS */ #endif #include #define HAS_UTMP_UT_HOST @@ -236,6 +247,10 @@ static Bool IsPts = False; #endif #endif /* } !SYSV */ +#ifdef USE_TTY_GROUP +#include +#endif + #ifdef _POSIX_SOURCE #define USE_POSIX_WAIT #define HAS_POSIX_SAVED_IDS @@ -251,6 +266,8 @@ static Bool IsPts = False; #if (BSD >= 199103) #define USE_POSIX_WAIT +#define LASTLOG +#define WTMP #define HAS_POSIX_SAVED_IDS #endif @@ -301,6 +318,10 @@ extern struct utmp *getutid __((struct u int Ptyfd; #endif /* PUCC_PTYD */ +#ifdef __OpenBSD__ +#include +#endif + #ifdef sequent #define USE_GET_PSEUDOTTY #endif @@ -362,6 +383,10 @@ int Ptyfd; #define SIGNAL_RETURN return #endif +#ifndef TTY_GROUP_NAME +#define TTY_GROUP_NAME "tty" +#endif + SIGNAL_T Exit(); #ifndef X_NOT_POSIX @@ -407,6 +432,10 @@ static Bool added_utmp_entry = False; static Bool xterm_exiting = False; +#ifdef __OpenBSD__ +static gid_t utmpGid = -1; +#endif + /* ** Ordinarily it should be okay to omit the assignment in the following ** statement. Apparently the c89 compiler on AIX 4.1.3 has a bug, or does @@ -416,6 +445,9 @@ static Bool xterm_exiting = False; */ static char **command_to_exec = NULL; +static int get_pty (int *pty); +static void set_owner (char *device, int uid, int gid, int mode); + #ifdef USE_SYSV_TERMIO /* The following structures are initialized in main() in order ** to eliminate any assumptions about the internal order of their @@ -434,6 +466,9 @@ static struct ltchars d_ltc; static unsigned int d_lmode; #endif /* TIOCLSET */ #else /* not USE_SYSV_TERMIO */ +#ifdef USE_POSIX_TERMIOS +static struct termios d_tio; +#else /* not USE_POSIX_TERMIOS */ static struct sgttyb d_sg = { 0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD }; @@ -457,6 +492,7 @@ static struct jtchars d_jtc = { 'J', 'B' }; #endif /* sony */ +#endif /* USE_POSIX_TERMIOS */ #endif /* USE_SYSV_TERMIO */ /* allow use of system default characters if defined and reasonable */ @@ -1107,37 +1143,47 @@ char **argv; char *base_name(); int xerror(), xioerror(); - XtSetLanguageProc (NULL, NULL, NULL); - ProgramName = argv[0]; /* +2 in case longer tty name like /dev/ttyq255 */ - ttydev = (char *) malloc (sizeof(TTYDEV) + 2); + ttydev = (char *) malloc (sizeof(TTYDEV) + 80); #ifndef __osf__ - ptydev = (char *) malloc (sizeof(PTYDEV) + 2); + ptydev = (char *) malloc (sizeof(PTYDEV) + 80); if (!ttydev || !ptydev) #else if (!ttydev) #endif { - fprintf (stderr, - "%s: unable to allocate memory for ttydev or ptydev\n", - ProgramName); - exit (1); + fprintf(stderr, + "%s: unable to allocate memory for ttydev or ptydev\n", + ProgramName); + exit (1); } strcpy (ttydev, TTYDEV); #ifndef __osf__ strcpy (ptydev, PTYDEV); #endif -#ifdef USE_SYSV_TERMIO /* { */ +#ifdef __OpenBSD__ + get_pty(NULL); + seteuid(getuid()); + setuid(getuid()); +#endif /* __OpenBSD__ */ + + XtSetLanguageProc (NULL, NULL, NULL); + +#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS) /* { */ /* Initialization is done here rather than above in order ** to prevent any assumptions about the order of the contents ** of the various terminal structures (which may change from ** implementation to implementation). */ d_tio.c_iflag = ICRNL|IXON; +#ifdef TAB3 d_tio.c_oflag = OPOST|ONLCR|TAB3; +#else + d_tio.c_oflag = OPOST|ONLCR; +#endif #if defined(macII) || defined(ATT) || defined(CRAY) /* { */ d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL; d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK; @@ -1161,9 +1207,11 @@ char **argv; d_tio.c_cc[VEOL2] = CNUL; d_tio.c_cc[VSWTCH] = CNUL; -#ifdef USE_TERMIOS /* { */ +#if defined(USE_TERMIOS) || defined(USE_POSIX_TERMIOS) /* { */ d_tio.c_cc[VSUSP] = CSUSP; +#ifdef VDSUSP d_tio.c_cc[VDSUSP] = CDSUSP; +#endif d_tio.c_cc[VREPRINT] = CRPRNT; d_tio.c_cc[VDISCARD] = CFLUSH; d_tio.c_cc[VWERASE] = CWERASE; @@ -1181,11 +1229,17 @@ char **argv; d_lmode = 0; #endif /* } TIOCLSET */ #else /* }{ else !macII, ATT, CRAY */ +#ifndef USE_POSIX_TERMIOS #ifdef BAUD_0 /* { */ d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL; #else /* }{ !BAUD_0 */ d_tio.c_cflag = B9600|CS8|CREAD|PARENB|HUPCL; #endif /* } !BAUD_0 */ +#else /* USE_POSIX_TERMIOS */ + d_tio.c_cflag = CS8|CREAD|PARENB|HUPCL; + cfsetispeed(&d_tio, B9600); + cfsetospeed(&d_tio, B9600); +#endif d_tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK; #ifdef ECHOKE d_tio.c_lflag |= ECHOKE|IEXTEN; @@ -1193,11 +1247,13 @@ char **argv; #ifdef ECHOCTL d_tio.c_lflag |= ECHOCTL|IEXTEN; #endif +#ifndef USE_POSIX_TERMIOS #ifdef NTTYDISC d_tio.c_line = NTTYDISC; #else d_tio.c_line = 0; #endif +#endif /* USE_POSIX_TERMIOS */ #ifdef __sgi d_tio.c_cflag &= ~(HUPCL|PARENB); d_tio.c_iflag |= BRKINT|ISTRIP|IGNPAR; @@ -1246,8 +1302,14 @@ char **argv; int i; for (i = 0; i <= 2; i++) { +#ifndef USE_POSIX_TERMIOS struct termio deftio; - if (ioctl (i, TCGETA, &deftio) == 0) { + if (ioctl (i, TCGETA, &deftio) == 0) +#else + struct termios deftio; + if (tcgetattr(i, &deftio) == 0) +#endif + { d_tio.c_cc[VINTR] = deftio.c_cc[VINTR]; d_tio.c_cc[VQUIT] = deftio.c_cc[VQUIT]; d_tio.c_cc[VERASE] = deftio.c_cc[VERASE]; @@ -1302,9 +1364,11 @@ char **argv; d_ltc.t_werasc = '\377'; d_ltc.t_lnextc = '\377'; #endif /* } TIOCSLTC */ -#ifdef USE_TERMIOS /* { */ +#if defined(USE_TERMIOS) || defined(USE_POSIX_TERMIOS) /* { */ d_tio.c_cc[VSUSP] = CSUSP; +#ifdef VDSUSP d_tio.c_cc[VDSUSP] = '\000'; +#endif d_tio.c_cc[VREPRINT] = '\377'; d_tio.c_cc[VDISCARD] = '\377'; d_tio.c_cc[VWERASE] = '\377'; @@ -1361,6 +1425,14 @@ char **argv; (void) fprintf(stderr, "setegid(%d): %s\n", (int) egid, strerror(errno)); #endif + +#ifdef __OpenBSD__ + if (resource.utmpInhibit) { + /* Can totally revoke group privs */ + setegid(getgid()); + setgid(getgid()); + } +#endif } waiting_for_initial_map = resource.wait_for_map; @@ -1719,6 +1791,32 @@ char *name; get_pty (pty) int *pty; { +#ifdef __OpenBSD__ + int result; + static int m_tty = -1; + static int m_pty = -1; + struct group *ttygrp; + + if (pty == NULL) { + result = openpty(&m_pty, &m_tty, ttydev, NULL, NULL); + + seteuid(0); + if ((ttygrp = getgrnam(TTY_GROUP_NAME)) != 0) { + set_owner(ttydev, getuid(), ttygrp->gr_gid, + 0600); + } else { + set_owner(ttydev, getuid(), getgid(), + 0600); + } + seteuid(getuid()); + return result; + } else if (m_pty != -1) { + *pty = m_pty; + return (0); + } else { + return (-1); + } +#endif /* __OpenBSD__ */ #ifdef __osf__ int tty; return (openpty(pty, &tty, ttydev, NULL, NULL)); @@ -2034,6 +2132,18 @@ void first_map_occurred () } #endif /* USE_HANDSHAKE else !USE_HANDSHAKE */ +static void +set_owner(char *device, int uid, int gid, int mode) +{ + if (chown (device, uid, gid) < 0) { + if (errno != ENOENT + && getuid() == 0) { + fprintf(stderr, "Cannot chown %s to %d,%d: %s\n", + device, uid, gid, strerror(errno)); + } + } + chmod (device, mode); +} spawn () /* @@ -2065,6 +2175,9 @@ spawn () int zero = 0; int status; #else /* else not USE_SYSV_TERMIO */ +#ifdef USE_POSIX_TERMIOS + struct termios tio; +#else /* else not USE_POSIX_TERMIOS */ unsigned lmode; struct tchars tc; struct ltchars ltc; @@ -2073,6 +2186,7 @@ spawn () int jmode; struct jtchars jtc; #endif /* sony */ +#endif /* USE_POSIX_TERMIOS */ #endif /* USE_SYSV_TERMIO */ char termcap [1024]; @@ -2168,9 +2282,9 @@ spawn () #ifdef TIOCLSET lmode = d_lmode; #endif /* TIOCLSET */ -#ifdef USE_SYSV_TERMIO +#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS) tio = d_tio; -#else /* not USE_SYSV_TERMIO */ +#else /* not USE_SYSV_TERMIO and not USE_POSIX_TERMIOS */ sg = d_sg; tc = d_tc; discipline = d_disipline; @@ -2178,7 +2292,7 @@ spawn () jmode = d_jmode; jtc = d_jtc; #endif /* sony */ -#endif /* USE_SYSV_TERMIO */ +#endif /* USE_SYSV_TERMIO or USE_POSIX_TERMIOS */ } else { SysError(ERROR_OPDEVTTY); } @@ -2202,6 +2316,10 @@ spawn () tio = d_tio; #else /* not USE_SYSV_TERMIO */ +#ifdef USE_POSIX_TERMIOS + if (tcgetattr(tty, &tio) == -1) + tio = d_tio; +#else /* not USE_POSIX_TERMIOS */ if(ioctl(tty, TIOCGETP, (char *)&sg) == -1) sg = d_sg; if(ioctl(tty, TIOCGETC, (char *)&tc) == -1) @@ -2214,6 +2332,7 @@ spawn () if(ioctl(tty, TIOCKGETC, (char *)&jtc) == -1) jtc = d_jtc; #endif /* sony */ +#endif /* USE_POSIX_TERMIOS */ #endif /* USE_SYSV_TERMIO */ close (tty); /* tty is no longer an open fd! */ @@ -2507,6 +2626,7 @@ spawn () break; #endif /* USE_SYSV_PGRP */ } + perror("open ttydev"); #ifdef TIOCSCTTY ioctl(tty, TIOCSCTTY, 0); @@ -2555,7 +2675,6 @@ spawn () #ifdef USE_TTY_GROUP { -#include struct group *ttygrp; if (ttygrp = getgrnam("tty")) { /* change ownership of tty to real uid, "tty" gid */ @@ -2581,7 +2700,7 @@ spawn () * set up the tty modes */ { -#ifdef USE_SYSV_TERMIO +#if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS) #if defined(umips) || defined(CRAY) || defined(linux) /* If the control tty had its modes screwed around with, eg. by lineedit in the shell, or emacs, etc. then tio @@ -2598,12 +2717,15 @@ spawn () tio.c_iflag &= ~(INLCR|IGNCR); tio.c_iflag |= ICRNL; /* ouput: cr->cr, nl is not return, no delays, ln->cr/nl */ +#ifndef USE_POSIX_TERMIOS tio.c_oflag &= ~(OCRNL|ONLRET|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); +#endif /* USE_POSIX_TERMIOS */ tio.c_oflag |= ONLCR; #ifdef OPOST tio.c_oflag |= OPOST; #endif /* OPOST */ +#ifndef USE_POSIX_TERMIOS #ifdef BAUD_0 /* baud rate is 0 (don't care) */ tio.c_cflag &= ~(CBAUD); @@ -2612,6 +2734,13 @@ spawn () tio.c_cflag &= ~(CBAUD); tio.c_cflag |= B9600; #endif /* !BAUD_0 */ +#else /* USE_POSIX_TERMIOS */ + cfsetispeed(&tio, B9600); + cfsetospeed(&tio, B9600); + /* Clear CLOCAL so that SIGHUP is sent to us + when the xterm ends */ + tio.c_cflag &= ~CLOCAL; +#endif /* USE_POSIX_TERMIOS */ tio.c_cflag &= ~CSIZE; if (screen->input_eight_bits) tio.c_cflag |= CS8; @@ -2723,9 +2852,14 @@ spawn () if (ioctl (tty, TIOCLSET, (char *)&lmode) == -1) HsSysError(cp_pipe[1], ERROR_TIOCLSET); #endif /* TIOCLSET */ +#ifndef USE_POSIX_TERMIOS if (ioctl (tty, TCSETA, &tio) == -1) HsSysError(cp_pipe[1], ERROR_TIOCSETP); -#else /* USE_SYSV_TERMIO */ +#else /* USE_POSIX_TERMIOS */ + if (tcsetattr (tty, TCSANOW, &tio) == -1) + HsSysError(cp_pipe[1], ERROR_TIOCSETP); +#endif /* USE_POSIX_TERMIOS */ +#else /* USE_SYSV_TERMIO or USE_POSIX_TERMIOS */ #ifdef KTERM sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW | EVENP | ODDP); @@ -3100,6 +3234,15 @@ spawn () close(i); } #endif /* LASTLOG */ + +#ifdef __OpenBSD__ + /* Switch to real gid after writing utmp entry */ + utmpGid = getegid(); + if (getgid() != getegid()) { + utmpGid = getegid(); + setegid(getgid()); + } +#endif } else tslot = -tslot; } @@ -3272,11 +3415,11 @@ spawn () shname_minus = malloc(strlen(shname) + 2); (void) strcpy(shname_minus, "-"); (void) strcat(shname_minus, shname); -#ifndef USE_SYSV_TERMIO +#if !defined(USE_SYSV_TERMIO) && !defined(USE_POSIX_TERMIOS) ldisc = XStrCmp("csh", shname + strlen(shname) - 3) == 0 ? NTTYDISC : 0; ioctl(0, TIOCSETD, (char *)&ldisc); -#endif /* !USE_SYSV_TERMIO */ +#endif /* !USE_SYSV_TERMIO && !USE_POSIX_TERMIOS */ #ifdef USE_LOGIN_DASH_P if (term->misc.login_shell && pw && added_utmp_entry) @@ -3459,6 +3602,12 @@ Exit(n) && added_utmp_entry #endif /* USE_HANDSHAKE */ ) { +#ifdef __OpenBSD__ + if (utmpGid != -1) { + /* Switch back to group utmp */ + setegid(utmpGid); + } +#endif ptyname = ttydev; utmp.ut_type = USER_PROCESS; if (PTYCHARLEN >= (int)strlen(ptyname))