121174Sdist /* 2*36517Skarels * 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[] = 20*36517Skarels "@(#) 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*36517Skarels static char sccsid[] = "@(#)rlogind.c 5.21 (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 3436453Skfall * data (not used currently) 3516369Skarels */ 3616369Skarels 376446Swnj #include <stdio.h> 386446Swnj #include <sys/types.h> 396446Swnj #include <sys/stat.h> 406446Swnj #include <sys/socket.h> 4113554Ssam #include <sys/wait.h> 4218357Ssam #include <sys/file.h> 439208Ssam 449208Ssam #include <netinet/in.h> 459208Ssam 466446Swnj #include <errno.h> 476446Swnj #include <pwd.h> 486446Swnj #include <signal.h> 4936453Skfall #include <sys/ioctl.h> 5036453Skfall #include <sys/termios.h> 516446Swnj #include <stdio.h> 528380Ssam #include <netdb.h> 5317187Sralph #include <syslog.h> 5418357Ssam #include <strings.h> 5536453Skfall #include <utmp.h> 566446Swnj 5736453Skfall #ifdef KERBEROS 5836453Skfall #include <sys/param.h> 5936453Skfall #include <kerberos/krb.h> 6036453Skfall #define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" 6136453Skfall 6236453Skfall AUTH_DAT *kdata; 6336453Skfall KTEXT ticket; 6436453Skfall u_char auth_buf[sizeof(AUTH_DAT)]; 6536453Skfall u_char tick_buf[sizeof(KTEXT_ST)]; 6636453Skfall Key_schedule schedule; 6736453Skfall int encrypt = 0, retval; 6836453Skfall int do_krb_login(); 6936453Skfall 7036453Skfall #define OLD_RCMD 0x00 7136453Skfall #define KERB_RCMD 0x01 7236453Skfall #define KERB_RCMD_MUTUAL 0x02 7336453Skfall #endif /* KERBEROS */ 7436453Skfall 7536453Skfall char *envinit[2]; 76*36517Skarels struct utmp utmp; 77*36517Skarels #define NMAX sizeof(utmp.ut_name) 78*36517Skarels char lusername[NMAX+1], rusername[NMAX+1]; 79*36517Skarels static char term[64] = "TERM="; 80*36517Skarels #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ 81*36517Skarels int keepalive = 1; 8236453Skfall 8336453Skfall #define SUPERUSER(pwd) ((pwd)->pw_uid == 0) 8436453Skfall 85*36517Skarels #ifndef TIOCPKT_WINDOW 86*36517Skarels #define TIOCPKT_WINDOW 0x80 87*36517Skarels #endif 8824723Smckusick 8934424Sbostic extern int errno; 9010417Ssam int reapchild(); 9136453Skfall struct passwd *getpwnam(), *pwd; 9224723Smckusick char *malloc(); 9316369Skarels 946446Swnj main(argc, argv) 956446Swnj int argc; 966446Swnj char **argv; 976446Swnj { 9836319Sbostic extern int opterr, optind, _check_rhosts_file; 9936319Sbostic int ch; 10034424Sbostic int on = 1, fromlen; 1016446Swnj struct sockaddr_in from; 1026446Swnj 10324855Seric openlog("rlogind", LOG_PID | LOG_AUTH, LOG_AUTH); 10436319Sbostic 10536319Sbostic opterr = 0; 106*36517Skarels while ((ch = getopt(argc, argv, "ln")) != EOF) 107*36517Skarels switch (ch) { 10836319Sbostic case 'l': 10936319Sbostic _check_rhosts_file = 0; 11036319Sbostic break; 111*36517Skarels case 'n': 112*36517Skarels keepalive = 0; 113*36517Skarels break; 11436319Sbostic case '?': 11536319Sbostic default: 116*36517Skarels syslog(LOG_ERR, "usage: rlogind [-l] [-n]"); 11736319Sbostic break; 11836319Sbostic } 11936319Sbostic argc -= optind; 12036319Sbostic argv += optind; 12136319Sbostic 12216369Skarels fromlen = sizeof (from); 12316369Skarels if (getpeername(0, &from, &fromlen) < 0) { 12416369Skarels fprintf(stderr, "%s: ", argv[0]); 12516369Skarels perror("getpeername"); 12636319Sbostic exit(1); 1278380Ssam } 128*36517Skarels if (keepalive && 129*36517Skarels setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) 13017187Sralph syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 13116369Skarels doit(0, &from); 1326446Swnj } 1336446Swnj 1346446Swnj int child; 1356446Swnj int cleanup(); 1366446Swnj int netf; 1376446Swnj char *line; 13824724Smckusick extern char *inet_ntoa(); 1396446Swnj 14024889Smckusick struct winsize win = { 0, 0, 0, 0 }; 14124723Smckusick 14224889Smckusick 1436446Swnj doit(f, fromp) 1446446Swnj int f; 1456446Swnj struct sockaddr_in *fromp; 1466446Swnj { 14718357Ssam int i, p, t, pid, on = 1; 14836453Skfall int authenticated = 0; 14918357Ssam register struct hostent *hp; 15024724Smckusick struct hostent hostent; 1518380Ssam char c; 1526446Swnj 1536446Swnj alarm(60); 1546446Swnj read(f, &c, 1); 15536453Skfall 15636453Skfall #ifdef KERBEROS 15736453Skfall /* 15836453Skfall * XXX 1st char tells us which client we're talking to 15936453Skfall */ 160*36517Skarels switch (c) { 16136453Skfall 162*36517Skarels case KERB_RCMD: 16336453Skfall break; 16436453Skfall 165*36517Skarels case KERB_RCMD_MUTUAL: 16636453Skfall encrypt = 1; 16736453Skfall break; 16836453Skfall 16936453Skfall 170*36517Skarels case OLD_RCMD: 17136453Skfall default: 17236453Skfall fatal(f, "Remote host requires Kerberos authentication"); 17336453Skfall } 17436453Skfall #else 1756446Swnj if (c != 0) 1766446Swnj exit(1); 17736453Skfall #endif 17836453Skfall 1796446Swnj alarm(0); 18016227Skarels fromp->sin_port = ntohs((u_short)fromp->sin_port); 1818380Ssam hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), 1828380Ssam fromp->sin_family); 18311345Ssam if (hp == 0) { 18424724Smckusick /* 18524724Smckusick * Only the name is used below. 18624724Smckusick */ 18724724Smckusick hp = &hostent; 18824724Smckusick hp->h_name = inet_ntoa(fromp->sin_addr); 18911345Ssam } 19036453Skfall 19136453Skfall #ifdef KERBEROS 19236453Skfall retval = do_krb_login(hp->h_name, fromp, encrypt); 19336453Skfall write(f, &c, 1); 194*36517Skarels if (retval == 0) 19536453Skfall authenticated++; 196*36517Skarels else 197*36517Skarels if (retval > 0) 19836453Skfall fatal(f, krb_err_txt[retval]); 19936453Skfall #else 2006446Swnj if (fromp->sin_family != AF_INET || 20132116Skarels fromp->sin_port >= IPPORT_RESERVED || 20232116Skarels fromp->sin_port < IPPORT_RESERVED/2) 2039242Ssam fatal(f, "Permission denied"); 2046446Swnj write(f, "", 1); 205*36517Skarels if (do_rlogin(hp->h_name) == 0) 20636453Skfall authenticated++; 20736453Skfall #endif 20836453Skfall 2096446Swnj for (c = 'p'; c <= 's'; c++) { 2106446Swnj struct stat stb; 2116446Swnj line = "/dev/ptyXX"; 2126446Swnj line[strlen("/dev/pty")] = c; 2136446Swnj line[strlen("/dev/ptyp")] = '0'; 2146446Swnj if (stat(line, &stb) < 0) 2156446Swnj break; 2166446Swnj for (i = 0; i < 16; i++) { 21734424Sbostic line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; 21834424Sbostic p = open(line, O_RDWR); 2196446Swnj if (p > 0) 2206446Swnj goto gotpty; 2216446Swnj } 2226446Swnj } 22324723Smckusick fatal(f, "Out of ptys"); 2249242Ssam /*NOTREACHED*/ 2256446Swnj gotpty: 22624889Smckusick (void) ioctl(p, TIOCSWINSZ, &win); 22716227Skarels netf = f; 2286446Swnj line[strlen("/dev/")] = 't'; 22934424Sbostic t = open(line, O_RDWR); 23034424Sbostic if (t < 0) 23134424Sbostic fatalperror(f, line); 23234424Sbostic if (fchmod(t, 0)) 23334424Sbostic fatalperror(f, line); 23434424Sbostic (void)signal(SIGHUP, SIG_IGN); 23534424Sbostic vhangup(); 23634424Sbostic (void)signal(SIGHUP, SIG_DFL); 23734424Sbostic t = open(line, O_RDWR); 23834424Sbostic if (t < 0) 23934424Sbostic fatalperror(f, line); 24036453Skfall setup_term(t); 2416446Swnj #ifdef DEBUG 24234424Sbostic { 24334424Sbostic int tt = open("/dev/tty", O_RDWR); 24434424Sbostic if (tt > 0) { 24534424Sbostic (void)ioctl(tt, TIOCNOTTY, 0); 24634424Sbostic (void)close(tt); 24734424Sbostic } 2486446Swnj } 2496446Swnj #endif 2509242Ssam pid = fork(); 2519242Ssam if (pid < 0) 25234424Sbostic fatalperror(f, ""); 25318357Ssam if (pid == 0) { 254*36517Skarels if (setsid() < 0) 25536453Skfall fatalperror(f, "setsid"); 256*36517Skarels if (ioctl(t, TIOCSCTTY, 0) < 0) 25736453Skfall fatalperror(f, "ioctl(sctty)"); 25818357Ssam close(f), close(p); 25918357Ssam dup2(t, 0), dup2(t, 1), dup2(t, 2); 26016227Skarels close(t); 261*36517Skarels if (authenticated) 262*36517Skarels execl("/bin/login", "login", "-p", "-f", 263*36517Skarels "-h", hp->h_name, pwd->pw_name, 0); 26436453Skfall else 265*36517Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 266*36517Skarels pwd->pw_name, 0); 26734424Sbostic fatalperror(2, "/bin/login"); 26818357Ssam /*NOTREACHED*/ 26918357Ssam } 27018357Ssam close(t); 27136453Skfall 27236453Skfall #ifdef KERBEROS 27336453Skfall /* 27436453Skfall * If encrypted, don't turn on NBIO or the des read/write 27536453Skfall * routines will croak. 27636453Skfall */ 27736453Skfall 278*36517Skarels if (encrypt) 27936453Skfall (void) des_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE)); 28036453Skfall else 281*36517Skarels #endif 28236453Skfall ioctl(f, FIONBIO, &on); 28336453Skfall 28418357Ssam ioctl(p, FIONBIO, &on); 28518357Ssam ioctl(p, TIOCPKT, &on); 28618357Ssam signal(SIGTSTP, SIG_IGN); 28718357Ssam signal(SIGCHLD, cleanup); 28824724Smckusick setpgrp(0, 0); 28918357Ssam protocol(f, p); 29030600Smckusick signal(SIGCHLD, SIG_IGN); 29118357Ssam cleanup(); 29218357Ssam } 2939242Ssam 29418357Ssam char magic[2] = { 0377, 0377 }; 29525423Skarels char oobdata[] = {TIOCPKT_WINDOW}; 29618357Ssam 29718357Ssam /* 29818357Ssam * Handle a "control" request (signaled by magic being present) 29918357Ssam * in the data stream. For now, we are only willing to handle 30018357Ssam * window size changes. 30118357Ssam */ 30218357Ssam control(pty, cp, n) 30318357Ssam int pty; 30418357Ssam char *cp; 30518357Ssam int n; 30618357Ssam { 30728705Smckusick struct winsize w; 30818357Ssam 30928705Smckusick if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 31018357Ssam return (0); 31125423Skarels oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 31228705Smckusick bcopy(cp+4, (char *)&w, sizeof(w)); 31328705Smckusick w.ws_row = ntohs(w.ws_row); 31428705Smckusick w.ws_col = ntohs(w.ws_col); 31528705Smckusick w.ws_xpixel = ntohs(w.ws_xpixel); 31628705Smckusick w.ws_ypixel = ntohs(w.ws_ypixel); 31728705Smckusick (void)ioctl(pty, TIOCSWINSZ, &w); 31828705Smckusick return (4+sizeof (w)); 31918357Ssam } 32018357Ssam 32118357Ssam /* 32218357Ssam * rlogin "protocol" machine. 32318357Ssam */ 32418357Ssam protocol(f, p) 32518357Ssam int f, p; 32618357Ssam { 32718357Ssam char pibuf[1024], fibuf[1024], *pbp, *fbp; 32818357Ssam register pcc = 0, fcc = 0; 329*36517Skarels int cc, nfd, pmask, fmask; 33025740Skarels char cntl; 33118357Ssam 33218482Ssam /* 33318484Ssam * Must ignore SIGTTOU, otherwise we'll stop 33418484Ssam * when we try and set slave pty's window shape 33525423Skarels * (our controlling tty is the master pty). 33618482Ssam */ 33718484Ssam (void) signal(SIGTTOU, SIG_IGN); 33825423Skarels send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 339*36517Skarels if (f > p) 340*36517Skarels nfd = f + 1; 341*36517Skarels else 342*36517Skarels nfd = p + 1; 343*36517Skarels fmask = 1 << f; 344*36517Skarels pmask = 1 << p; 34518357Ssam for (;;) { 34625740Skarels int ibits, obits, ebits; 34718357Ssam 34825740Skarels ibits = 0; 34925740Skarels obits = 0; 35018357Ssam if (fcc) 351*36517Skarels obits |= pmask; 35218357Ssam else 353*36517Skarels ibits |= fmask; 35418357Ssam if (pcc >= 0) 35518357Ssam if (pcc) 356*36517Skarels obits |= fmask; 3579242Ssam else 358*36517Skarels ibits |= pmask; 359*36517Skarels ebits = pmask; 360*36517Skarels if (select(nfd, &ibits, obits ? &obits : (int *)NULL, 361*36517Skarels &ebits, 0) < 0) { 36218357Ssam if (errno == EINTR) 3636446Swnj continue; 36434424Sbostic fatalperror(f, "select"); 36518357Ssam } 36625740Skarels if (ibits == 0 && obits == 0 && ebits == 0) { 36718357Ssam /* shouldn't happen... */ 36818357Ssam sleep(5); 36918357Ssam continue; 37018357Ssam } 37125740Skarels #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 372*36517Skarels if (ebits & pmask) { 37325740Skarels cc = read(p, &cntl, 1); 37425740Skarels if (cc == 1 && pkcontrol(cntl)) { 37525740Skarels cntl |= oobdata[0]; 37625740Skarels send(f, &cntl, 1, MSG_OOB); 37725740Skarels if (cntl & TIOCPKT_FLUSHWRITE) { 37825740Skarels pcc = 0; 379*36517Skarels ibits &= ~pmask; 38025740Skarels } 38125740Skarels } 38225740Skarels } 383*36517Skarels if (ibits & fmask) { 38436453Skfall #ifdef KERBEROS 385*36517Skarels if (encrypt) 38636453Skfall fcc = des_read(f, fibuf, sizeof(fibuf)); 387*36517Skarels else 388*36517Skarels #endif 38936453Skfall fcc = read(f, fibuf, sizeof(fibuf)); 39018357Ssam if (fcc < 0 && errno == EWOULDBLOCK) 39118357Ssam fcc = 0; 39218357Ssam else { 39318357Ssam register char *cp; 39418357Ssam int left, n; 39518357Ssam 39618357Ssam if (fcc <= 0) 39716227Skarels break; 39818357Ssam fbp = fibuf; 39924723Smckusick 40018357Ssam top: 40125423Skarels for (cp = fibuf; cp < fibuf+fcc-1; cp++) 40218357Ssam if (cp[0] == magic[0] && 40318357Ssam cp[1] == magic[1]) { 40418357Ssam left = fcc - (cp-fibuf); 40518357Ssam n = control(p, cp, left); 40618357Ssam if (n) { 40718357Ssam left -= n; 40818357Ssam if (left > 0) 40925423Skarels bcopy(cp+n, cp, left); 41018357Ssam fcc -= n; 41118357Ssam goto top; /* n^2 */ 41225423Skarels } 41325423Skarels } 414*36517Skarels obits |= pmask; /* try write */ 41525423Skarels } 41625423Skarels } 41724723Smckusick 418*36517Skarels if ((obits & pmask) && fcc > 0) { 41925423Skarels cc = write(p, fbp, fcc); 42024723Smckusick if (cc > 0) { 42124723Smckusick fcc -= cc; 42224723Smckusick fbp += cc; 4236446Swnj } 42418357Ssam } 42524723Smckusick 426*36517Skarels if (ibits & pmask) { 42718357Ssam pcc = read(p, pibuf, sizeof (pibuf)); 42818357Ssam pbp = pibuf; 42918357Ssam if (pcc < 0 && errno == EWOULDBLOCK) 43018357Ssam pcc = 0; 43118357Ssam else if (pcc <= 0) 43218357Ssam break; 433*36517Skarels else if (pibuf[0] == 0) { 43418357Ssam pbp++, pcc--; 435*36517Skarels #ifdef KERBEROS 436*36517Skarels if (!encrypt) 437*36517Skarels #endif 438*36517Skarels obits |= fmask; /* try a write */ 439*36517Skarels } else { 44018357Ssam if (pkcontrol(pibuf[0])) { 44125423Skarels pibuf[0] |= oobdata[0]; 44218357Ssam send(f, &pibuf[0], 1, MSG_OOB); 44316227Skarels } 44418357Ssam pcc = 0; 4456446Swnj } 44618357Ssam } 447*36517Skarels if ((obits & fmask) && pcc > 0) { 44836453Skfall #ifdef KERBEROS 449*36517Skarels if (encrypt) 45036453Skfall cc = des_write(f, pbp, pcc); 451*36517Skarels else 452*36517Skarels #endif 45336453Skfall cc = write(f, pbp, pcc); 45425423Skarels if (cc < 0 && errno == EWOULDBLOCK) { 45525423Skarels /* also shouldn't happen */ 45625423Skarels sleep(5); 45725423Skarels continue; 45825423Skarels } 45918357Ssam if (cc > 0) { 46018357Ssam pcc -= cc; 46118357Ssam pbp += cc; 46218357Ssam } 4636446Swnj } 4646446Swnj } 4656446Swnj } 4666446Swnj 4676446Swnj cleanup() 4686446Swnj { 46935440Sbostic char *p; 47035440Sbostic 47135440Sbostic p = line + sizeof("/dev/") - 1; 47235440Sbostic if (logout(p)) 47335440Sbostic logwtmp(p, "", ""); 47435440Sbostic (void)chmod(line, 0666); 47535440Sbostic (void)chown(line, 0, 0); 47635440Sbostic *p = 'p'; 47735440Sbostic (void)chmod(line, 0666); 47835440Sbostic (void)chown(line, 0, 0); 47910192Ssam shutdown(netf, 2); 4806446Swnj exit(1); 4816446Swnj } 4826446Swnj 4839242Ssam fatal(f, msg) 4849242Ssam int f; 4859242Ssam char *msg; 4869242Ssam { 4879242Ssam char buf[BUFSIZ]; 4889242Ssam 4899242Ssam buf[0] = '\01'; /* error indicator */ 49013554Ssam (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg); 4919242Ssam (void) write(f, buf, strlen(buf)); 4929242Ssam exit(1); 4939242Ssam } 4949242Ssam 49534424Sbostic fatalperror(f, msg) 4969242Ssam int f; 4979242Ssam char *msg; 4989242Ssam { 4999242Ssam char buf[BUFSIZ]; 50016227Skarels extern int sys_nerr; 5019242Ssam extern char *sys_errlist[]; 5029242Ssam 50318357Ssam if ((unsigned)errno < sys_nerr) 50416227Skarels (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]); 50516227Skarels else 50616227Skarels (void) sprintf(buf, "%s: Error %d", msg, errno); 5079242Ssam fatal(f, buf); 5089242Ssam } 50936453Skfall 51036453Skfall 51136453Skfall int 51236453Skfall do_rlogin(host) 51336453Skfall char *host; 51436453Skfall { 51536453Skfall getstr(rusername, sizeof(rusername), "remuser"); 51636453Skfall getstr(lusername, sizeof(lusername), "locuser"); 51736453Skfall getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); 51836453Skfall 51936453Skfall if(getuid()) { 52036453Skfall pwd = &nouser; 52136453Skfall return(-1); 52236453Skfall } 52336453Skfall pwd = getpwnam(lusername); 52436453Skfall if(pwd == NULL) { 52536453Skfall pwd = &nouser; 52636453Skfall pwd->pw_name = lusername; /* pass on to login */ 52736453Skfall return(-1); 52836453Skfall } 52936453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 53036453Skfall } 53136453Skfall 53236453Skfall 53336453Skfall getstr(buf, cnt, err) 53436453Skfall char *buf; 53536453Skfall int cnt; 53636453Skfall char *err; 53736453Skfall { 53836453Skfall char c; 53936453Skfall do { 54036453Skfall if(read(0, &c, 1) != 1) 54136453Skfall exit(1); 54236453Skfall if(--cnt < 0) { 54336453Skfall printf("%s too long\r\n", err); 54436453Skfall exit(1); 54536453Skfall } 54636453Skfall *buf++ = c; 54736453Skfall } while(c != 0); 54836453Skfall } 54936453Skfall 55036453Skfall extern char **environ; 55136453Skfall 55236453Skfall setup_term(fd) 55336453Skfall int fd; 55436453Skfall { 55536453Skfall struct termios tt; 55636453Skfall struct sgttyb tp; 55736453Skfall register char *cp = index(term+ENVSIZE, '/'), **cpp; 55836453Skfall char *speed; 55936453Skfall 56036453Skfall tcgetattr(fd, &tt); 56136453Skfall if(cp) { 56236453Skfall *cp++ = '\0'; 56336453Skfall speed = cp; 56436453Skfall cp = index(speed, '/'); 56536453Skfall if(cp) 56636453Skfall *cp++ = '\0'; 56736453Skfall cfsetspeed(&tt, atoi(speed)); 56836453Skfall } 56936453Skfall tt.c_iflag = BRKINT|ICRNL|IXON|ISTRIP|IEXTEN|IMAXBEL; 57036453Skfall tt.c_oflag = OPOST|ONLCR|OXTABS; 57136453Skfall tt.c_lflag = ISIG|ICANON|ECHO; 57236453Skfall tcsetattr(fd, TCSADFLUSH, &tt); 57336453Skfall 57436453Skfall envinit[0] = term; 57536453Skfall envinit[1] = 0; 57636453Skfall environ = envinit; 57736453Skfall } 57836453Skfall 57936453Skfall #ifdef KERBEROS 58036453Skfall #define VERSION_SIZE 9 58136453Skfall 58236453Skfall /* 58336453Skfall * Do the remote kerberos login to the named host with the 58436453Skfall * given inet address 58536453Skfall * 58636453Skfall * Return 0 on valid authorization 58736453Skfall * Return -1 on valid authentication, no authorization 58836453Skfall * Return >0 for error conditions 58936453Skfall */ 59036453Skfall 59136453Skfall int 59236453Skfall do_krb_login(host, dest, encrypt) 59336453Skfall char *host; 59436453Skfall struct sockaddr_in *dest; 59536453Skfall int encrypt; 59636453Skfall { 59736453Skfall int rc; 59836453Skfall char instance[INST_SZ], version[VERSION_SIZE]; 59936453Skfall long authopts = 0L; /* !mutual */ 60036453Skfall struct sockaddr_in faddr; 60136453Skfall 60236453Skfall if(getuid()) { 60336453Skfall pwd = &nouser; 60436453Skfall return(KFAILURE); 60536453Skfall } 60636453Skfall 60736453Skfall kdata = (AUTH_DAT *) auth_buf; 60836453Skfall ticket = (KTEXT) tick_buf; 60936453Skfall strcpy(instance, "*"); 61036453Skfall 61136453Skfall if(encrypt) { 61236453Skfall rc = sizeof(faddr); 61336453Skfall if(getsockname(0, &faddr, &rc)) { 61436453Skfall pwd = &nouser; 61536453Skfall return(-1); 61636453Skfall } 61736453Skfall authopts = KOPT_DO_MUTUAL; 61836453Skfall rc = krb_recvauth( 61936453Skfall authopts, 0, 62036453Skfall ticket, "rcmd", 62136453Skfall instance, dest, &faddr, 622*36517Skarels kdata, "", schedule, version); 62336453Skfall des_set_key(kdata->session, schedule); 62436453Skfall 62536453Skfall } else { 62636453Skfall rc = krb_recvauth( 62736453Skfall authopts, 0, 62836453Skfall ticket, "rcmd", 62936453Skfall instance, dest, (struct sockaddr_in *) 0, 630*36517Skarels kdata, "", (bit_64 *) 0, version); 63136453Skfall } 63236453Skfall 63336453Skfall if(rc != KSUCCESS) { 63436453Skfall pwd = &nouser; 63536453Skfall return(rc); 63636453Skfall } 63736453Skfall 63836453Skfall if((rc = krb_kntoln(kdata, rusername)) != KSUCCESS) { 63936453Skfall pwd = &nouser; 64036453Skfall return(rc); 64136453Skfall } 64236453Skfall 64336453Skfall getstr(lusername, sizeof(lusername), "locuser"); 64436453Skfall /* get the "cmd" in the rcmd protocol */ 64536453Skfall getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); 64636453Skfall 64736453Skfall pwd = getpwnam(lusername); 64836453Skfall if(pwd == NULL) { 64936453Skfall pwd = &nouser; 65036453Skfall pwd->pw_name = lusername; 65136453Skfall return(-1); 65236453Skfall } 65336453Skfall 65436453Skfall /* XXX need to use something other than ruserok */ 65536453Skfall /* returns -1 for invalid authentication */ 65636453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 65736453Skfall } 65836453Skfall #endif 659