121174Sdist /* 236517Skarels * Copyright (c) 1983, 1988 The Regents of the University of California. 335441Sbostic * All rights reserved. 435441Sbostic * 535441Sbostic * Redistribution and use in source and binary forms are permitted 635441Sbostic * provided that the above copyright notice and this paragraph are 735441Sbostic * duplicated in all such forms and that any documentation, 835441Sbostic * advertising materials, and other materials related to such 935441Sbostic * distribution and use acknowledge that the software was developed 1035441Sbostic * by the University of California, Berkeley. The name of the 1135441Sbostic * University may not be used to endorse or promote products derived 1235441Sbostic * from this software without specific prior written permission. 1335441Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435441Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535441Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621174Sdist */ 1721174Sdist 186446Swnj #ifndef lint 1921174Sdist char copyright[] = 2036517Skarels "@(#) Copyright (c) 1983, 1988 The Regents of the University of California.\n\ 2121174Sdist All rights reserved.\n"; 2235441Sbostic #endif /* not lint */ 236446Swnj 2421174Sdist #ifndef lint 25*36519Skarels static char sccsid[] = "@(#)rlogind.c 5.22.1.1 (Berkeley) 01/06/89"; 2635441Sbostic #endif /* not lint */ 2721174Sdist 2816369Skarels /* 2916369Skarels * remote login server: 3036453Skfall * \0 3116369Skarels * remuser\0 3216369Skarels * locuser\0 3336453Skfall * terminal_type/speed\0 3436518Skarels * data 35*36519Skarels * 36*36519Skarels * Automatic login protocol is done here, using login -f upon success, 37*36519Skarels * unless OLD_LOGIN is defined (then done in login, ala 4.2/4.3BSD). 3816369Skarels */ 3916369Skarels 406446Swnj #include <stdio.h> 416446Swnj #include <sys/types.h> 426446Swnj #include <sys/stat.h> 436446Swnj #include <sys/socket.h> 4413554Ssam #include <sys/wait.h> 4518357Ssam #include <sys/file.h> 469208Ssam 479208Ssam #include <netinet/in.h> 489208Ssam 496446Swnj #include <errno.h> 506446Swnj #include <pwd.h> 516446Swnj #include <signal.h> 52*36519Skarels #ifndef TERMIOS 53*36519Skarels #include <sgtty.h> 54*36519Skarels #else /* TERMIOS */ 5536453Skfall #include <sys/ioctl.h> 5636453Skfall #include <sys/termios.h> 57*36519Skarels #endif /* TERMIOS */ 586446Swnj #include <stdio.h> 598380Ssam #include <netdb.h> 6017187Sralph #include <syslog.h> 6118357Ssam #include <strings.h> 626446Swnj 6336518Skarels #ifndef TIOCPKT_WINDOW 6436518Skarels #define TIOCPKT_WINDOW 0x80 6536518Skarels #endif 6636518Skarels 6736453Skfall #ifdef KERBEROS 6836453Skfall #include <sys/param.h> 6936453Skfall #include <kerberos/krb.h> 7036453Skfall #define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" 7136453Skfall 7236453Skfall AUTH_DAT *kdata; 7336453Skfall KTEXT ticket; 7436453Skfall u_char auth_buf[sizeof(AUTH_DAT)]; 7536453Skfall u_char tick_buf[sizeof(KTEXT_ST)]; 7636453Skfall Key_schedule schedule; 7736518Skarels int encrypt, retval; 7836453Skfall int do_krb_login(); 7936453Skfall 8036453Skfall #define OLD_RCMD 0x00 8136453Skfall #define KERB_RCMD 0x01 8236453Skfall #define KERB_RCMD_MUTUAL 0x02 8336453Skfall #endif /* KERBEROS */ 8436453Skfall 8536518Skarels char *env[2]; 8636518Skarels #define NMAX 30 8736517Skarels char lusername[NMAX+1], rusername[NMAX+1]; 8836517Skarels static char term[64] = "TERM="; 8936517Skarels #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ 9036517Skarels int keepalive = 1; 9136453Skfall 9236453Skfall #define SUPERUSER(pwd) ((pwd)->pw_uid == 0) 9336453Skfall 9434424Sbostic extern int errno; 9510417Ssam int reapchild(); 9636453Skfall struct passwd *getpwnam(), *pwd; 9724723Smckusick char *malloc(); 9816369Skarels 996446Swnj main(argc, argv) 1006446Swnj int argc; 1016446Swnj char **argv; 1026446Swnj { 10336319Sbostic extern int opterr, optind, _check_rhosts_file; 10436319Sbostic int ch; 10534424Sbostic int on = 1, fromlen; 1066446Swnj struct sockaddr_in from; 1076446Swnj 10824855Seric openlog("rlogind", LOG_PID | LOG_AUTH, LOG_AUTH); 10936319Sbostic 11036319Sbostic opterr = 0; 11136517Skarels while ((ch = getopt(argc, argv, "ln")) != EOF) 11236517Skarels switch (ch) { 11336319Sbostic case 'l': 11436319Sbostic _check_rhosts_file = 0; 11536319Sbostic break; 11636517Skarels case 'n': 11736517Skarels keepalive = 0; 11836517Skarels break; 11936319Sbostic case '?': 12036319Sbostic default: 12136517Skarels syslog(LOG_ERR, "usage: rlogind [-l] [-n]"); 12236319Sbostic break; 12336319Sbostic } 12436319Sbostic argc -= optind; 12536319Sbostic argv += optind; 12636319Sbostic 12716369Skarels fromlen = sizeof (from); 12816369Skarels if (getpeername(0, &from, &fromlen) < 0) { 12916369Skarels fprintf(stderr, "%s: ", argv[0]); 13016369Skarels perror("getpeername"); 13136319Sbostic exit(1); 1328380Ssam } 13336517Skarels if (keepalive && 13436517Skarels setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) 13517187Sralph syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 13616369Skarels doit(0, &from); 1376446Swnj } 1386446Swnj 1396446Swnj int child; 1406446Swnj int cleanup(); 1416446Swnj int netf; 1426446Swnj char *line; 14324724Smckusick extern char *inet_ntoa(); 1446446Swnj 14524889Smckusick struct winsize win = { 0, 0, 0, 0 }; 14624723Smckusick 14724889Smckusick 1486446Swnj doit(f, fromp) 1496446Swnj int f; 1506446Swnj struct sockaddr_in *fromp; 1516446Swnj { 15218357Ssam int i, p, t, pid, on = 1; 153*36519Skarels #ifndef OLD_LOGIN 15436518Skarels int authenticated = 0; 155*36519Skarels #endif 15618357Ssam register struct hostent *hp; 15724724Smckusick struct hostent hostent; 1588380Ssam char c; 1596446Swnj 1606446Swnj alarm(60); 1616446Swnj read(f, &c, 1); 16236453Skfall 16336453Skfall #ifdef KERBEROS 16436453Skfall /* 16536453Skfall * XXX 1st char tells us which client we're talking to 16636453Skfall */ 16736517Skarels switch (c) { 16836453Skfall 16936517Skarels case KERB_RCMD: 17036453Skfall break; 17136453Skfall 17236517Skarels case KERB_RCMD_MUTUAL: 17336453Skfall encrypt = 1; 17436453Skfall break; 17536453Skfall 17636453Skfall 17736517Skarels case OLD_RCMD: 17836453Skfall default: 17936453Skfall fatal(f, "Remote host requires Kerberos authentication"); 18036453Skfall } 18136453Skfall #else 1826446Swnj if (c != 0) 1836446Swnj exit(1); 18436453Skfall #endif 18536453Skfall 1866446Swnj alarm(0); 18716227Skarels fromp->sin_port = ntohs((u_short)fromp->sin_port); 1888380Ssam hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), 1898380Ssam fromp->sin_family); 19011345Ssam if (hp == 0) { 19124724Smckusick /* 19224724Smckusick * Only the name is used below. 19324724Smckusick */ 19424724Smckusick hp = &hostent; 19524724Smckusick hp->h_name = inet_ntoa(fromp->sin_addr); 19611345Ssam } 19736453Skfall 19836453Skfall #ifdef KERBEROS 19936453Skfall retval = do_krb_login(hp->h_name, fromp, encrypt); 20036453Skfall write(f, &c, 1); 20136517Skarels if (retval == 0) 20236453Skfall authenticated++; 20336517Skarels else 20436517Skarels if (retval > 0) 20536453Skfall fatal(f, krb_err_txt[retval]); 20636453Skfall #else 2076446Swnj if (fromp->sin_family != AF_INET || 20832116Skarels fromp->sin_port >= IPPORT_RESERVED || 20932116Skarels fromp->sin_port < IPPORT_RESERVED/2) 2109242Ssam fatal(f, "Permission denied"); 2116446Swnj write(f, "", 1); 21236518Skarels #endif 213*36519Skarels #ifndef OLD_LOGIN 21436517Skarels if (do_rlogin(hp->h_name) == 0) 21536453Skfall authenticated++; 216*36519Skarels #endif 21736453Skfall 2186446Swnj for (c = 'p'; c <= 's'; c++) { 2196446Swnj struct stat stb; 2206446Swnj line = "/dev/ptyXX"; 2216446Swnj line[strlen("/dev/pty")] = c; 2226446Swnj line[strlen("/dev/ptyp")] = '0'; 2236446Swnj if (stat(line, &stb) < 0) 2246446Swnj break; 2256446Swnj for (i = 0; i < 16; i++) { 22634424Sbostic line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; 22734424Sbostic p = open(line, O_RDWR); 2286446Swnj if (p > 0) 2296446Swnj goto gotpty; 2306446Swnj } 2316446Swnj } 23224723Smckusick fatal(f, "Out of ptys"); 2339242Ssam /*NOTREACHED*/ 2346446Swnj gotpty: 23524889Smckusick (void) ioctl(p, TIOCSWINSZ, &win); 23616227Skarels netf = f; 2376446Swnj line[strlen("/dev/")] = 't'; 23834424Sbostic t = open(line, O_RDWR); 23934424Sbostic if (t < 0) 24034424Sbostic fatalperror(f, line); 24134424Sbostic if (fchmod(t, 0)) 24234424Sbostic fatalperror(f, line); 24334424Sbostic (void)signal(SIGHUP, SIG_IGN); 24434424Sbostic vhangup(); 24534424Sbostic (void)signal(SIGHUP, SIG_DFL); 24634424Sbostic t = open(line, O_RDWR); 24734424Sbostic if (t < 0) 24834424Sbostic fatalperror(f, line); 24936453Skfall setup_term(t); 2506446Swnj #ifdef DEBUG 25134424Sbostic { 25234424Sbostic int tt = open("/dev/tty", O_RDWR); 25334424Sbostic if (tt > 0) { 25434424Sbostic (void)ioctl(tt, TIOCNOTTY, 0); 25534424Sbostic (void)close(tt); 25634424Sbostic } 2576446Swnj } 2586446Swnj #endif 2599242Ssam pid = fork(); 2609242Ssam if (pid < 0) 26134424Sbostic fatalperror(f, ""); 26218357Ssam if (pid == 0) { 263*36519Skarels #ifdef TERMIOS 26436517Skarels if (setsid() < 0) 26536453Skfall fatalperror(f, "setsid"); 26636517Skarels if (ioctl(t, TIOCSCTTY, 0) < 0) 26736453Skfall fatalperror(f, "ioctl(sctty)"); 268*36519Skarels #endif /* TERMIOS */ 26918357Ssam close(f), close(p); 27018357Ssam dup2(t, 0), dup2(t, 1), dup2(t, 2); 27116227Skarels close(t); 272*36519Skarels #ifdef OLD_LOGIN 273*36519Skarels execl("/bin/login", "login", "-r", hp->h_name, 0); 274*36519Skarels #else /* OLD_LOGIN */ 27536517Skarels if (authenticated) 27636517Skarels execl("/bin/login", "login", "-p", "-f", 27736518Skarels "-h", hp->h_name, lusername, 0); 27836453Skfall else 27936517Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 28036518Skarels lusername, 0); 281*36519Skarels #endif /* OLD_LOGIN */ 28234424Sbostic fatalperror(2, "/bin/login"); 28318357Ssam /*NOTREACHED*/ 28418357Ssam } 28518357Ssam close(t); 28636453Skfall 28736453Skfall #ifdef KERBEROS 28836453Skfall /* 28936453Skfall * If encrypted, don't turn on NBIO or the des read/write 29036453Skfall * routines will croak. 29136453Skfall */ 29236453Skfall 29336517Skarels if (encrypt) 29436453Skfall (void) des_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE)); 29536453Skfall else 29636517Skarels #endif 29736453Skfall ioctl(f, FIONBIO, &on); 29818357Ssam ioctl(p, FIONBIO, &on); 29918357Ssam ioctl(p, TIOCPKT, &on); 30018357Ssam signal(SIGTSTP, SIG_IGN); 30118357Ssam signal(SIGCHLD, cleanup); 30224724Smckusick setpgrp(0, 0); 30318357Ssam protocol(f, p); 30430600Smckusick signal(SIGCHLD, SIG_IGN); 30518357Ssam cleanup(); 30618357Ssam } 3079242Ssam 30818357Ssam char magic[2] = { 0377, 0377 }; 30925423Skarels char oobdata[] = {TIOCPKT_WINDOW}; 31018357Ssam 31118357Ssam /* 31218357Ssam * Handle a "control" request (signaled by magic being present) 31318357Ssam * in the data stream. For now, we are only willing to handle 31418357Ssam * window size changes. 31518357Ssam */ 31618357Ssam control(pty, cp, n) 31718357Ssam int pty; 31818357Ssam char *cp; 31918357Ssam int n; 32018357Ssam { 32128705Smckusick struct winsize w; 32218357Ssam 32328705Smckusick if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 32418357Ssam return (0); 32525423Skarels oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 32628705Smckusick bcopy(cp+4, (char *)&w, sizeof(w)); 32728705Smckusick w.ws_row = ntohs(w.ws_row); 32828705Smckusick w.ws_col = ntohs(w.ws_col); 32928705Smckusick w.ws_xpixel = ntohs(w.ws_xpixel); 33028705Smckusick w.ws_ypixel = ntohs(w.ws_ypixel); 33128705Smckusick (void)ioctl(pty, TIOCSWINSZ, &w); 33228705Smckusick return (4+sizeof (w)); 33318357Ssam } 33418357Ssam 33518357Ssam /* 33618357Ssam * rlogin "protocol" machine. 33718357Ssam */ 33818357Ssam protocol(f, p) 33918357Ssam int f, p; 34018357Ssam { 34118357Ssam char pibuf[1024], fibuf[1024], *pbp, *fbp; 34218357Ssam register pcc = 0, fcc = 0; 34336517Skarels int cc, nfd, pmask, fmask; 34425740Skarels char cntl; 34518357Ssam 34618482Ssam /* 34718484Ssam * Must ignore SIGTTOU, otherwise we'll stop 34818484Ssam * when we try and set slave pty's window shape 34925423Skarels * (our controlling tty is the master pty). 35018482Ssam */ 35118484Ssam (void) signal(SIGTTOU, SIG_IGN); 35225423Skarels send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 35336517Skarels if (f > p) 35436517Skarels nfd = f + 1; 35536517Skarels else 35636517Skarels nfd = p + 1; 35736517Skarels fmask = 1 << f; 35836517Skarels pmask = 1 << p; 35918357Ssam for (;;) { 36025740Skarels int ibits, obits, ebits; 36118357Ssam 36225740Skarels ibits = 0; 36325740Skarels obits = 0; 36418357Ssam if (fcc) 36536517Skarels obits |= pmask; 36618357Ssam else 36736517Skarels ibits |= fmask; 36818357Ssam if (pcc >= 0) 36918357Ssam if (pcc) 37036517Skarels obits |= fmask; 3719242Ssam else 37236517Skarels ibits |= pmask; 37336517Skarels ebits = pmask; 37436517Skarels if (select(nfd, &ibits, obits ? &obits : (int *)NULL, 37536517Skarels &ebits, 0) < 0) { 37618357Ssam if (errno == EINTR) 3776446Swnj continue; 37834424Sbostic fatalperror(f, "select"); 37918357Ssam } 38025740Skarels if (ibits == 0 && obits == 0 && ebits == 0) { 38118357Ssam /* shouldn't happen... */ 38218357Ssam sleep(5); 38318357Ssam continue; 38418357Ssam } 38525740Skarels #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 38636517Skarels if (ebits & pmask) { 38725740Skarels cc = read(p, &cntl, 1); 38825740Skarels if (cc == 1 && pkcontrol(cntl)) { 38925740Skarels cntl |= oobdata[0]; 39025740Skarels send(f, &cntl, 1, MSG_OOB); 39125740Skarels if (cntl & TIOCPKT_FLUSHWRITE) { 39225740Skarels pcc = 0; 39336517Skarels ibits &= ~pmask; 39425740Skarels } 39525740Skarels } 39625740Skarels } 39736517Skarels if (ibits & fmask) { 39836453Skfall #ifdef KERBEROS 39936517Skarels if (encrypt) 40036453Skfall fcc = des_read(f, fibuf, sizeof(fibuf)); 40136517Skarels else 40236517Skarels #endif 40336453Skfall fcc = read(f, fibuf, sizeof(fibuf)); 40418357Ssam if (fcc < 0 && errno == EWOULDBLOCK) 40518357Ssam fcc = 0; 40618357Ssam else { 40718357Ssam register char *cp; 40818357Ssam int left, n; 40918357Ssam 41018357Ssam if (fcc <= 0) 41116227Skarels break; 41218357Ssam fbp = fibuf; 41324723Smckusick 41418357Ssam top: 41525423Skarels for (cp = fibuf; cp < fibuf+fcc-1; cp++) 41618357Ssam if (cp[0] == magic[0] && 41718357Ssam cp[1] == magic[1]) { 41818357Ssam left = fcc - (cp-fibuf); 41918357Ssam n = control(p, cp, left); 42018357Ssam if (n) { 42118357Ssam left -= n; 42218357Ssam if (left > 0) 42325423Skarels bcopy(cp+n, cp, left); 42418357Ssam fcc -= n; 42518357Ssam goto top; /* n^2 */ 42625423Skarels } 42725423Skarels } 42836517Skarels obits |= pmask; /* try write */ 42925423Skarels } 43025423Skarels } 43124723Smckusick 43236517Skarels if ((obits & pmask) && fcc > 0) { 43325423Skarels cc = write(p, fbp, fcc); 43424723Smckusick if (cc > 0) { 43524723Smckusick fcc -= cc; 43624723Smckusick fbp += cc; 4376446Swnj } 43818357Ssam } 43924723Smckusick 44036517Skarels if (ibits & pmask) { 44118357Ssam pcc = read(p, pibuf, sizeof (pibuf)); 44218357Ssam pbp = pibuf; 44318357Ssam if (pcc < 0 && errno == EWOULDBLOCK) 44418357Ssam pcc = 0; 44518357Ssam else if (pcc <= 0) 44618357Ssam break; 44736517Skarels else if (pibuf[0] == 0) { 44818357Ssam pbp++, pcc--; 44936517Skarels #ifdef KERBEROS 45036517Skarels if (!encrypt) 45136517Skarels #endif 45236517Skarels obits |= fmask; /* try a write */ 45336517Skarels } else { 45418357Ssam if (pkcontrol(pibuf[0])) { 45525423Skarels pibuf[0] |= oobdata[0]; 45618357Ssam send(f, &pibuf[0], 1, MSG_OOB); 45716227Skarels } 45818357Ssam pcc = 0; 4596446Swnj } 46018357Ssam } 46136517Skarels if ((obits & fmask) && pcc > 0) { 46236453Skfall #ifdef KERBEROS 46336517Skarels if (encrypt) 46436453Skfall cc = des_write(f, pbp, pcc); 46536517Skarels else 46636517Skarels #endif 46736453Skfall cc = write(f, pbp, pcc); 46825423Skarels if (cc < 0 && errno == EWOULDBLOCK) { 46925423Skarels /* also shouldn't happen */ 47025423Skarels sleep(5); 47125423Skarels continue; 47225423Skarels } 47318357Ssam if (cc > 0) { 47418357Ssam pcc -= cc; 47518357Ssam pbp += cc; 47618357Ssam } 4776446Swnj } 4786446Swnj } 4796446Swnj } 4806446Swnj 4816446Swnj cleanup() 4826446Swnj { 48335440Sbostic char *p; 48435440Sbostic 48535440Sbostic p = line + sizeof("/dev/") - 1; 48635440Sbostic if (logout(p)) 48735440Sbostic logwtmp(p, "", ""); 48835440Sbostic (void)chmod(line, 0666); 48935440Sbostic (void)chown(line, 0, 0); 49035440Sbostic *p = 'p'; 49135440Sbostic (void)chmod(line, 0666); 49235440Sbostic (void)chown(line, 0, 0); 49310192Ssam shutdown(netf, 2); 4946446Swnj exit(1); 4956446Swnj } 4966446Swnj 4979242Ssam fatal(f, msg) 4989242Ssam int f; 4999242Ssam char *msg; 5009242Ssam { 5019242Ssam char buf[BUFSIZ]; 5029242Ssam 5039242Ssam buf[0] = '\01'; /* error indicator */ 50413554Ssam (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg); 5059242Ssam (void) write(f, buf, strlen(buf)); 5069242Ssam exit(1); 5079242Ssam } 5089242Ssam 50934424Sbostic fatalperror(f, msg) 5109242Ssam int f; 5119242Ssam char *msg; 5129242Ssam { 5139242Ssam char buf[BUFSIZ]; 51416227Skarels extern int sys_nerr; 5159242Ssam extern char *sys_errlist[]; 5169242Ssam 51718357Ssam if ((unsigned)errno < sys_nerr) 51816227Skarels (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]); 51916227Skarels else 52016227Skarels (void) sprintf(buf, "%s: Error %d", msg, errno); 5219242Ssam fatal(f, buf); 5229242Ssam } 52336453Skfall 524*36519Skarels #ifndef OLD_LOGIN 52536453Skfall do_rlogin(host) 52636518Skarels char *host; 52736453Skfall { 52836453Skfall 52936518Skarels getstr(rusername, sizeof(rusername), "remuser too long"); 53036518Skarels getstr(lusername, sizeof(lusername), "locuser too long"); 53136518Skarels getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); 53236518Skarels 53336518Skarels if (getuid()) 53436453Skfall return(-1); 53536453Skfall pwd = getpwnam(lusername); 53636518Skarels if (pwd == NULL) 53736453Skfall return(-1); 53836453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 53936453Skfall } 54036453Skfall 54136453Skfall 54236518Skarels getstr(buf, cnt, errmsg) 54336518Skarels char *buf; 54436518Skarels int cnt; 54536518Skarels char *errmsg; 54636453Skfall { 54736518Skarels char c; 54836518Skarels 54936453Skfall do { 55036518Skarels if (read(0, &c, 1) != 1) 55136453Skfall exit(1); 55236518Skarels if (--cnt < 0) 55336518Skarels fatal(1, errmsg); 55436453Skfall *buf++ = c; 55536518Skarels } while (c != 0); 55636453Skfall } 55736453Skfall 55836518Skarels extern char **environ; 55936453Skfall 560*36519Skarels #ifdef TERMIOS 56136453Skfall setup_term(fd) 56236518Skarels int fd; 56336453Skfall { 56436518Skarels struct termios tt; 56536518Skarels register char *cp = index(term+ENVSIZE, '/'); 56636518Skarels char *speed; 56736453Skfall 56836453Skfall tcgetattr(fd, &tt); 56936518Skarels if (cp) { 57036453Skfall *cp++ = '\0'; 57136453Skfall speed = cp; 57236453Skfall cp = index(speed, '/'); 57336518Skarels if (cp) 57436453Skfall *cp++ = '\0'; 57536453Skfall cfsetspeed(&tt, atoi(speed)); 57636453Skfall } 57736453Skfall tt.c_iflag = BRKINT|ICRNL|IXON|ISTRIP|IEXTEN|IMAXBEL; 57836453Skfall tt.c_oflag = OPOST|ONLCR|OXTABS; 57936453Skfall tt.c_lflag = ISIG|ICANON|ECHO; 58036453Skfall tcsetattr(fd, TCSADFLUSH, &tt); 58136453Skfall 58236518Skarels env[0] = term; 58336518Skarels env[1] = 0; 58436518Skarels environ = env; 58536453Skfall } 586*36519Skarels #else /* TERMIOS */ 587*36519Skarels char *speeds[] = { 588*36519Skarels "0", "50", "75", "110", "134", "150", "200", "300", "600", 589*36519Skarels "1200", "1800", "2400", "4800", "9600", "19200", "38400", 590*36519Skarels }; 591*36519Skarels #define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) 59236453Skfall 593*36519Skarels setup_term(fd) 594*36519Skarels int fd; 595*36519Skarels { 596*36519Skarels register char *cp = index(term, '/'), **cpp; 597*36519Skarels struct sgttyb sgttyb; 598*36519Skarels char *speed; 599*36519Skarels 600*36519Skarels (void)ioctl(fd, TIOCGETP, &sgttyb); 601*36519Skarels if (cp) { 602*36519Skarels *cp++ = '\0'; 603*36519Skarels speed = cp; 604*36519Skarels cp = index(speed, '/'); 605*36519Skarels if (cp) 606*36519Skarels *cp++ = '\0'; 607*36519Skarels for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 608*36519Skarels if (strcmp(*cpp, speed) == 0) { 609*36519Skarels sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds; 610*36519Skarels break; 611*36519Skarels } 612*36519Skarels } 613*36519Skarels sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; 614*36519Skarels (void)ioctl(fd, TIOCSETP, &sgttyb); 615*36519Skarels 616*36519Skarels env[0] = term; 617*36519Skarels env[1] = 0; 618*36519Skarels environ = env; 619*36519Skarels } 620*36519Skarels #endif /* TERMIOS */ 621*36519Skarels #endif /* OLD_LOGIN */ 622*36519Skarels 62336453Skfall #ifdef KERBEROS 62436453Skfall #define VERSION_SIZE 9 62536453Skfall 62636453Skfall /* 62736453Skfall * Do the remote kerberos login to the named host with the 62836453Skfall * given inet address 62936453Skfall * 63036453Skfall * Return 0 on valid authorization 63136453Skfall * Return -1 on valid authentication, no authorization 63236453Skfall * Return >0 for error conditions 63336453Skfall */ 63436453Skfall do_krb_login(host, dest, encrypt) 63536518Skarels char *host; 63636518Skarels struct sockaddr_in *dest; 63736518Skarels int encrypt; 63836453Skfall { 63936518Skarels int rc; 64036518Skarels char instance[INST_SZ], version[VERSION_SIZE]; 64136518Skarels long authopts = 0L; /* !mutual */ 64236518Skarels struct sockaddr_in faddr; 64336453Skfall 64436518Skarels if (getuid()) 64536453Skfall return(KFAILURE); 64636453Skfall 64736453Skfall kdata = (AUTH_DAT *) auth_buf; 64836453Skfall ticket = (KTEXT) tick_buf; 64936453Skfall strcpy(instance, "*"); 65036453Skfall 65136518Skarels if (encrypt) { 65236453Skfall rc = sizeof(faddr); 65336518Skarels if (getsockname(0, &faddr, &rc)) 65436453Skfall return(-1); 65536453Skfall authopts = KOPT_DO_MUTUAL; 65636453Skfall rc = krb_recvauth( 65736453Skfall authopts, 0, 65836453Skfall ticket, "rcmd", 65936453Skfall instance, dest, &faddr, 66036517Skarels kdata, "", schedule, version); 66136453Skfall des_set_key(kdata->session, schedule); 66236453Skfall 66336453Skfall } else { 66436453Skfall rc = krb_recvauth( 66536453Skfall authopts, 0, 66636453Skfall ticket, "rcmd", 66736453Skfall instance, dest, (struct sockaddr_in *) 0, 66836517Skarels kdata, "", (bit_64 *) 0, version); 66936453Skfall } 67036453Skfall 67136518Skarels if (rc != KSUCCESS) 67236453Skfall return(rc); 67336453Skfall 67436518Skarels if ((rc = krb_kntoln(kdata, rusername)) != KSUCCESS) 67536453Skfall return(rc); 67636453Skfall 67736453Skfall getstr(lusername, sizeof(lusername), "locuser"); 67836453Skfall /* get the "cmd" in the rcmd protocol */ 67936453Skfall getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); 68036453Skfall 68136453Skfall pwd = getpwnam(lusername); 68236518Skarels if (pwd == NULL) 68336453Skfall return(-1); 68436453Skfall 68536453Skfall /* XXX need to use something other than ruserok */ 68636453Skfall /* returns -1 for invalid authentication */ 68736453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 68836453Skfall } 68936518Skarels #endif /* KERBEROS */ 690