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*36518Skarels static char sccsid[] = "@(#)rlogind.c 5.22 (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 34*36518Skarels * data 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> 556446Swnj 56*36518Skarels #ifndef TIOCPKT_WINDOW 57*36518Skarels #define TIOCPKT_WINDOW 0x80 58*36518Skarels #endif 59*36518Skarels 6036453Skfall #ifdef KERBEROS 6136453Skfall #include <sys/param.h> 6236453Skfall #include <kerberos/krb.h> 6336453Skfall #define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" 6436453Skfall 6536453Skfall AUTH_DAT *kdata; 6636453Skfall KTEXT ticket; 6736453Skfall u_char auth_buf[sizeof(AUTH_DAT)]; 6836453Skfall u_char tick_buf[sizeof(KTEXT_ST)]; 6936453Skfall Key_schedule schedule; 70*36518Skarels int encrypt, retval; 7136453Skfall int do_krb_login(); 7236453Skfall 7336453Skfall #define OLD_RCMD 0x00 7436453Skfall #define KERB_RCMD 0x01 7536453Skfall #define KERB_RCMD_MUTUAL 0x02 7636453Skfall #endif /* KERBEROS */ 7736453Skfall 78*36518Skarels char *env[2]; 79*36518Skarels #define NMAX 30 8036517Skarels char lusername[NMAX+1], rusername[NMAX+1]; 8136517Skarels static char term[64] = "TERM="; 8236517Skarels #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ 8336517Skarels int keepalive = 1; 8436453Skfall 8536453Skfall #define SUPERUSER(pwd) ((pwd)->pw_uid == 0) 8636453Skfall 8734424Sbostic extern int errno; 8810417Ssam int reapchild(); 8936453Skfall struct passwd *getpwnam(), *pwd; 9024723Smckusick char *malloc(); 9116369Skarels 926446Swnj main(argc, argv) 936446Swnj int argc; 946446Swnj char **argv; 956446Swnj { 9636319Sbostic extern int opterr, optind, _check_rhosts_file; 9736319Sbostic int ch; 9834424Sbostic int on = 1, fromlen; 996446Swnj struct sockaddr_in from; 1006446Swnj 10124855Seric openlog("rlogind", LOG_PID | LOG_AUTH, LOG_AUTH); 10236319Sbostic 10336319Sbostic opterr = 0; 10436517Skarels while ((ch = getopt(argc, argv, "ln")) != EOF) 10536517Skarels switch (ch) { 10636319Sbostic case 'l': 10736319Sbostic _check_rhosts_file = 0; 10836319Sbostic break; 10936517Skarels case 'n': 11036517Skarels keepalive = 0; 11136517Skarels break; 11236319Sbostic case '?': 11336319Sbostic default: 11436517Skarels syslog(LOG_ERR, "usage: rlogind [-l] [-n]"); 11536319Sbostic break; 11636319Sbostic } 11736319Sbostic argc -= optind; 11836319Sbostic argv += optind; 11936319Sbostic 12016369Skarels fromlen = sizeof (from); 12116369Skarels if (getpeername(0, &from, &fromlen) < 0) { 12216369Skarels fprintf(stderr, "%s: ", argv[0]); 12316369Skarels perror("getpeername"); 12436319Sbostic exit(1); 1258380Ssam } 12636517Skarels if (keepalive && 12736517Skarels setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) 12817187Sralph syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 12916369Skarels doit(0, &from); 1306446Swnj } 1316446Swnj 1326446Swnj int child; 1336446Swnj int cleanup(); 1346446Swnj int netf; 1356446Swnj char *line; 13624724Smckusick extern char *inet_ntoa(); 1376446Swnj 13824889Smckusick struct winsize win = { 0, 0, 0, 0 }; 13924723Smckusick 14024889Smckusick 1416446Swnj doit(f, fromp) 1426446Swnj int f; 1436446Swnj struct sockaddr_in *fromp; 1446446Swnj { 14518357Ssam int i, p, t, pid, on = 1; 146*36518Skarels int authenticated = 0; 14718357Ssam register struct hostent *hp; 14824724Smckusick struct hostent hostent; 1498380Ssam char c; 1506446Swnj 1516446Swnj alarm(60); 1526446Swnj read(f, &c, 1); 15336453Skfall 15436453Skfall #ifdef KERBEROS 15536453Skfall /* 15636453Skfall * XXX 1st char tells us which client we're talking to 15736453Skfall */ 15836517Skarels switch (c) { 15936453Skfall 16036517Skarels case KERB_RCMD: 16136453Skfall break; 16236453Skfall 16336517Skarels case KERB_RCMD_MUTUAL: 16436453Skfall encrypt = 1; 16536453Skfall break; 16636453Skfall 16736453Skfall 16836517Skarels case OLD_RCMD: 16936453Skfall default: 17036453Skfall fatal(f, "Remote host requires Kerberos authentication"); 17136453Skfall } 17236453Skfall #else 1736446Swnj if (c != 0) 1746446Swnj exit(1); 17536453Skfall #endif 17636453Skfall 1776446Swnj alarm(0); 17816227Skarels fromp->sin_port = ntohs((u_short)fromp->sin_port); 1798380Ssam hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), 1808380Ssam fromp->sin_family); 18111345Ssam if (hp == 0) { 18224724Smckusick /* 18324724Smckusick * Only the name is used below. 18424724Smckusick */ 18524724Smckusick hp = &hostent; 18624724Smckusick hp->h_name = inet_ntoa(fromp->sin_addr); 18711345Ssam } 18836453Skfall 18936453Skfall #ifdef KERBEROS 19036453Skfall retval = do_krb_login(hp->h_name, fromp, encrypt); 19136453Skfall write(f, &c, 1); 19236517Skarels if (retval == 0) 19336453Skfall authenticated++; 19436517Skarels else 19536517Skarels if (retval > 0) 19636453Skfall fatal(f, krb_err_txt[retval]); 19736453Skfall #else 1986446Swnj if (fromp->sin_family != AF_INET || 19932116Skarels fromp->sin_port >= IPPORT_RESERVED || 20032116Skarels fromp->sin_port < IPPORT_RESERVED/2) 2019242Ssam fatal(f, "Permission denied"); 2026446Swnj write(f, "", 1); 203*36518Skarels #endif 20436517Skarels if (do_rlogin(hp->h_name) == 0) 20536453Skfall authenticated++; 20636453Skfall 2076446Swnj for (c = 'p'; c <= 's'; c++) { 2086446Swnj struct stat stb; 2096446Swnj line = "/dev/ptyXX"; 2106446Swnj line[strlen("/dev/pty")] = c; 2116446Swnj line[strlen("/dev/ptyp")] = '0'; 2126446Swnj if (stat(line, &stb) < 0) 2136446Swnj break; 2146446Swnj for (i = 0; i < 16; i++) { 21534424Sbostic line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; 21634424Sbostic p = open(line, O_RDWR); 2176446Swnj if (p > 0) 2186446Swnj goto gotpty; 2196446Swnj } 2206446Swnj } 22124723Smckusick fatal(f, "Out of ptys"); 2229242Ssam /*NOTREACHED*/ 2236446Swnj gotpty: 22424889Smckusick (void) ioctl(p, TIOCSWINSZ, &win); 22516227Skarels netf = f; 2266446Swnj line[strlen("/dev/")] = 't'; 22734424Sbostic t = open(line, O_RDWR); 22834424Sbostic if (t < 0) 22934424Sbostic fatalperror(f, line); 23034424Sbostic if (fchmod(t, 0)) 23134424Sbostic fatalperror(f, line); 23234424Sbostic (void)signal(SIGHUP, SIG_IGN); 23334424Sbostic vhangup(); 23434424Sbostic (void)signal(SIGHUP, SIG_DFL); 23534424Sbostic t = open(line, O_RDWR); 23634424Sbostic if (t < 0) 23734424Sbostic fatalperror(f, line); 23836453Skfall setup_term(t); 2396446Swnj #ifdef DEBUG 24034424Sbostic { 24134424Sbostic int tt = open("/dev/tty", O_RDWR); 24234424Sbostic if (tt > 0) { 24334424Sbostic (void)ioctl(tt, TIOCNOTTY, 0); 24434424Sbostic (void)close(tt); 24534424Sbostic } 2466446Swnj } 2476446Swnj #endif 2489242Ssam pid = fork(); 2499242Ssam if (pid < 0) 25034424Sbostic fatalperror(f, ""); 25118357Ssam if (pid == 0) { 25236517Skarels if (setsid() < 0) 25336453Skfall fatalperror(f, "setsid"); 25436517Skarels if (ioctl(t, TIOCSCTTY, 0) < 0) 25536453Skfall fatalperror(f, "ioctl(sctty)"); 25618357Ssam close(f), close(p); 25718357Ssam dup2(t, 0), dup2(t, 1), dup2(t, 2); 25816227Skarels close(t); 25936517Skarels if (authenticated) 26036517Skarels execl("/bin/login", "login", "-p", "-f", 261*36518Skarels "-h", hp->h_name, lusername, 0); 26236453Skfall else 26336517Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 264*36518Skarels lusername, 0); 26534424Sbostic fatalperror(2, "/bin/login"); 26618357Ssam /*NOTREACHED*/ 26718357Ssam } 26818357Ssam close(t); 26936453Skfall 27036453Skfall #ifdef KERBEROS 27136453Skfall /* 27236453Skfall * If encrypted, don't turn on NBIO or the des read/write 27336453Skfall * routines will croak. 27436453Skfall */ 27536453Skfall 27636517Skarels if (encrypt) 27736453Skfall (void) des_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE)); 27836453Skfall else 27936517Skarels #endif 28036453Skfall ioctl(f, FIONBIO, &on); 28118357Ssam ioctl(p, FIONBIO, &on); 28218357Ssam ioctl(p, TIOCPKT, &on); 28318357Ssam signal(SIGTSTP, SIG_IGN); 28418357Ssam signal(SIGCHLD, cleanup); 28524724Smckusick setpgrp(0, 0); 28618357Ssam protocol(f, p); 28730600Smckusick signal(SIGCHLD, SIG_IGN); 28818357Ssam cleanup(); 28918357Ssam } 2909242Ssam 29118357Ssam char magic[2] = { 0377, 0377 }; 29225423Skarels char oobdata[] = {TIOCPKT_WINDOW}; 29318357Ssam 29418357Ssam /* 29518357Ssam * Handle a "control" request (signaled by magic being present) 29618357Ssam * in the data stream. For now, we are only willing to handle 29718357Ssam * window size changes. 29818357Ssam */ 29918357Ssam control(pty, cp, n) 30018357Ssam int pty; 30118357Ssam char *cp; 30218357Ssam int n; 30318357Ssam { 30428705Smckusick struct winsize w; 30518357Ssam 30628705Smckusick if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 30718357Ssam return (0); 30825423Skarels oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 30928705Smckusick bcopy(cp+4, (char *)&w, sizeof(w)); 31028705Smckusick w.ws_row = ntohs(w.ws_row); 31128705Smckusick w.ws_col = ntohs(w.ws_col); 31228705Smckusick w.ws_xpixel = ntohs(w.ws_xpixel); 31328705Smckusick w.ws_ypixel = ntohs(w.ws_ypixel); 31428705Smckusick (void)ioctl(pty, TIOCSWINSZ, &w); 31528705Smckusick return (4+sizeof (w)); 31618357Ssam } 31718357Ssam 31818357Ssam /* 31918357Ssam * rlogin "protocol" machine. 32018357Ssam */ 32118357Ssam protocol(f, p) 32218357Ssam int f, p; 32318357Ssam { 32418357Ssam char pibuf[1024], fibuf[1024], *pbp, *fbp; 32518357Ssam register pcc = 0, fcc = 0; 32636517Skarels int cc, nfd, pmask, fmask; 32725740Skarels char cntl; 32818357Ssam 32918482Ssam /* 33018484Ssam * Must ignore SIGTTOU, otherwise we'll stop 33118484Ssam * when we try and set slave pty's window shape 33225423Skarels * (our controlling tty is the master pty). 33318482Ssam */ 33418484Ssam (void) signal(SIGTTOU, SIG_IGN); 33525423Skarels send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 33636517Skarels if (f > p) 33736517Skarels nfd = f + 1; 33836517Skarels else 33936517Skarels nfd = p + 1; 34036517Skarels fmask = 1 << f; 34136517Skarels pmask = 1 << p; 34218357Ssam for (;;) { 34325740Skarels int ibits, obits, ebits; 34418357Ssam 34525740Skarels ibits = 0; 34625740Skarels obits = 0; 34718357Ssam if (fcc) 34836517Skarels obits |= pmask; 34918357Ssam else 35036517Skarels ibits |= fmask; 35118357Ssam if (pcc >= 0) 35218357Ssam if (pcc) 35336517Skarels obits |= fmask; 3549242Ssam else 35536517Skarels ibits |= pmask; 35636517Skarels ebits = pmask; 35736517Skarels if (select(nfd, &ibits, obits ? &obits : (int *)NULL, 35836517Skarels &ebits, 0) < 0) { 35918357Ssam if (errno == EINTR) 3606446Swnj continue; 36134424Sbostic fatalperror(f, "select"); 36218357Ssam } 36325740Skarels if (ibits == 0 && obits == 0 && ebits == 0) { 36418357Ssam /* shouldn't happen... */ 36518357Ssam sleep(5); 36618357Ssam continue; 36718357Ssam } 36825740Skarels #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 36936517Skarels if (ebits & pmask) { 37025740Skarels cc = read(p, &cntl, 1); 37125740Skarels if (cc == 1 && pkcontrol(cntl)) { 37225740Skarels cntl |= oobdata[0]; 37325740Skarels send(f, &cntl, 1, MSG_OOB); 37425740Skarels if (cntl & TIOCPKT_FLUSHWRITE) { 37525740Skarels pcc = 0; 37636517Skarels ibits &= ~pmask; 37725740Skarels } 37825740Skarels } 37925740Skarels } 38036517Skarels if (ibits & fmask) { 38136453Skfall #ifdef KERBEROS 38236517Skarels if (encrypt) 38336453Skfall fcc = des_read(f, fibuf, sizeof(fibuf)); 38436517Skarels else 38536517Skarels #endif 38636453Skfall fcc = read(f, fibuf, sizeof(fibuf)); 38718357Ssam if (fcc < 0 && errno == EWOULDBLOCK) 38818357Ssam fcc = 0; 38918357Ssam else { 39018357Ssam register char *cp; 39118357Ssam int left, n; 39218357Ssam 39318357Ssam if (fcc <= 0) 39416227Skarels break; 39518357Ssam fbp = fibuf; 39624723Smckusick 39718357Ssam top: 39825423Skarels for (cp = fibuf; cp < fibuf+fcc-1; cp++) 39918357Ssam if (cp[0] == magic[0] && 40018357Ssam cp[1] == magic[1]) { 40118357Ssam left = fcc - (cp-fibuf); 40218357Ssam n = control(p, cp, left); 40318357Ssam if (n) { 40418357Ssam left -= n; 40518357Ssam if (left > 0) 40625423Skarels bcopy(cp+n, cp, left); 40718357Ssam fcc -= n; 40818357Ssam goto top; /* n^2 */ 40925423Skarels } 41025423Skarels } 41136517Skarels obits |= pmask; /* try write */ 41225423Skarels } 41325423Skarels } 41424723Smckusick 41536517Skarels if ((obits & pmask) && fcc > 0) { 41625423Skarels cc = write(p, fbp, fcc); 41724723Smckusick if (cc > 0) { 41824723Smckusick fcc -= cc; 41924723Smckusick fbp += cc; 4206446Swnj } 42118357Ssam } 42224723Smckusick 42336517Skarels if (ibits & pmask) { 42418357Ssam pcc = read(p, pibuf, sizeof (pibuf)); 42518357Ssam pbp = pibuf; 42618357Ssam if (pcc < 0 && errno == EWOULDBLOCK) 42718357Ssam pcc = 0; 42818357Ssam else if (pcc <= 0) 42918357Ssam break; 43036517Skarels else if (pibuf[0] == 0) { 43118357Ssam pbp++, pcc--; 43236517Skarels #ifdef KERBEROS 43336517Skarels if (!encrypt) 43436517Skarels #endif 43536517Skarels obits |= fmask; /* try a write */ 43636517Skarels } else { 43718357Ssam if (pkcontrol(pibuf[0])) { 43825423Skarels pibuf[0] |= oobdata[0]; 43918357Ssam send(f, &pibuf[0], 1, MSG_OOB); 44016227Skarels } 44118357Ssam pcc = 0; 4426446Swnj } 44318357Ssam } 44436517Skarels if ((obits & fmask) && pcc > 0) { 44536453Skfall #ifdef KERBEROS 44636517Skarels if (encrypt) 44736453Skfall cc = des_write(f, pbp, pcc); 44836517Skarels else 44936517Skarels #endif 45036453Skfall cc = write(f, pbp, pcc); 45125423Skarels if (cc < 0 && errno == EWOULDBLOCK) { 45225423Skarels /* also shouldn't happen */ 45325423Skarels sleep(5); 45425423Skarels continue; 45525423Skarels } 45618357Ssam if (cc > 0) { 45718357Ssam pcc -= cc; 45818357Ssam pbp += cc; 45918357Ssam } 4606446Swnj } 4616446Swnj } 4626446Swnj } 4636446Swnj 4646446Swnj cleanup() 4656446Swnj { 46635440Sbostic char *p; 46735440Sbostic 46835440Sbostic p = line + sizeof("/dev/") - 1; 46935440Sbostic if (logout(p)) 47035440Sbostic logwtmp(p, "", ""); 47135440Sbostic (void)chmod(line, 0666); 47235440Sbostic (void)chown(line, 0, 0); 47335440Sbostic *p = 'p'; 47435440Sbostic (void)chmod(line, 0666); 47535440Sbostic (void)chown(line, 0, 0); 47610192Ssam shutdown(netf, 2); 4776446Swnj exit(1); 4786446Swnj } 4796446Swnj 4809242Ssam fatal(f, msg) 4819242Ssam int f; 4829242Ssam char *msg; 4839242Ssam { 4849242Ssam char buf[BUFSIZ]; 4859242Ssam 4869242Ssam buf[0] = '\01'; /* error indicator */ 48713554Ssam (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg); 4889242Ssam (void) write(f, buf, strlen(buf)); 4899242Ssam exit(1); 4909242Ssam } 4919242Ssam 49234424Sbostic fatalperror(f, msg) 4939242Ssam int f; 4949242Ssam char *msg; 4959242Ssam { 4969242Ssam char buf[BUFSIZ]; 49716227Skarels extern int sys_nerr; 4989242Ssam extern char *sys_errlist[]; 4999242Ssam 50018357Ssam if ((unsigned)errno < sys_nerr) 50116227Skarels (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]); 50216227Skarels else 50316227Skarels (void) sprintf(buf, "%s: Error %d", msg, errno); 5049242Ssam fatal(f, buf); 5059242Ssam } 50636453Skfall 50736453Skfall do_rlogin(host) 508*36518Skarels char *host; 50936453Skfall { 51036453Skfall 511*36518Skarels getstr(rusername, sizeof(rusername), "remuser too long"); 512*36518Skarels getstr(lusername, sizeof(lusername), "locuser too long"); 513*36518Skarels getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); 514*36518Skarels 515*36518Skarels if (getuid()) 51636453Skfall return(-1); 51736453Skfall pwd = getpwnam(lusername); 518*36518Skarels if (pwd == NULL) 51936453Skfall return(-1); 52036453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 52136453Skfall } 52236453Skfall 52336453Skfall 524*36518Skarels getstr(buf, cnt, errmsg) 525*36518Skarels char *buf; 526*36518Skarels int cnt; 527*36518Skarels char *errmsg; 52836453Skfall { 529*36518Skarels char c; 530*36518Skarels 53136453Skfall do { 532*36518Skarels if (read(0, &c, 1) != 1) 53336453Skfall exit(1); 534*36518Skarels if (--cnt < 0) 535*36518Skarels fatal(1, errmsg); 53636453Skfall *buf++ = c; 537*36518Skarels } while (c != 0); 53836453Skfall } 53936453Skfall 540*36518Skarels extern char **environ; 54136453Skfall 54236453Skfall setup_term(fd) 543*36518Skarels int fd; 54436453Skfall { 545*36518Skarels struct termios tt; 546*36518Skarels register char *cp = index(term+ENVSIZE, '/'); 547*36518Skarels char *speed; 54836453Skfall 54936453Skfall tcgetattr(fd, &tt); 550*36518Skarels if (cp) { 55136453Skfall *cp++ = '\0'; 55236453Skfall speed = cp; 55336453Skfall cp = index(speed, '/'); 554*36518Skarels if (cp) 55536453Skfall *cp++ = '\0'; 55636453Skfall cfsetspeed(&tt, atoi(speed)); 55736453Skfall } 55836453Skfall tt.c_iflag = BRKINT|ICRNL|IXON|ISTRIP|IEXTEN|IMAXBEL; 55936453Skfall tt.c_oflag = OPOST|ONLCR|OXTABS; 56036453Skfall tt.c_lflag = ISIG|ICANON|ECHO; 56136453Skfall tcsetattr(fd, TCSADFLUSH, &tt); 56236453Skfall 563*36518Skarels env[0] = term; 564*36518Skarels env[1] = 0; 565*36518Skarels environ = env; 56636453Skfall } 56736453Skfall 56836453Skfall #ifdef KERBEROS 56936453Skfall #define VERSION_SIZE 9 57036453Skfall 57136453Skfall /* 57236453Skfall * Do the remote kerberos login to the named host with the 57336453Skfall * given inet address 57436453Skfall * 57536453Skfall * Return 0 on valid authorization 57636453Skfall * Return -1 on valid authentication, no authorization 57736453Skfall * Return >0 for error conditions 57836453Skfall */ 57936453Skfall do_krb_login(host, dest, encrypt) 580*36518Skarels char *host; 581*36518Skarels struct sockaddr_in *dest; 582*36518Skarels int encrypt; 58336453Skfall { 584*36518Skarels int rc; 585*36518Skarels char instance[INST_SZ], version[VERSION_SIZE]; 586*36518Skarels long authopts = 0L; /* !mutual */ 587*36518Skarels struct sockaddr_in faddr; 58836453Skfall 589*36518Skarels if (getuid()) 59036453Skfall return(KFAILURE); 59136453Skfall 59236453Skfall kdata = (AUTH_DAT *) auth_buf; 59336453Skfall ticket = (KTEXT) tick_buf; 59436453Skfall strcpy(instance, "*"); 59536453Skfall 596*36518Skarels if (encrypt) { 59736453Skfall rc = sizeof(faddr); 598*36518Skarels if (getsockname(0, &faddr, &rc)) 59936453Skfall return(-1); 60036453Skfall authopts = KOPT_DO_MUTUAL; 60136453Skfall rc = krb_recvauth( 60236453Skfall authopts, 0, 60336453Skfall ticket, "rcmd", 60436453Skfall instance, dest, &faddr, 60536517Skarels kdata, "", schedule, version); 60636453Skfall des_set_key(kdata->session, schedule); 60736453Skfall 60836453Skfall } else { 60936453Skfall rc = krb_recvauth( 61036453Skfall authopts, 0, 61136453Skfall ticket, "rcmd", 61236453Skfall instance, dest, (struct sockaddr_in *) 0, 61336517Skarels kdata, "", (bit_64 *) 0, version); 61436453Skfall } 61536453Skfall 616*36518Skarels if (rc != KSUCCESS) 61736453Skfall return(rc); 61836453Skfall 619*36518Skarels if ((rc = krb_kntoln(kdata, rusername)) != KSUCCESS) 62036453Skfall return(rc); 62136453Skfall 62236453Skfall getstr(lusername, sizeof(lusername), "locuser"); 62336453Skfall /* get the "cmd" in the rcmd protocol */ 62436453Skfall getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); 62536453Skfall 62636453Skfall pwd = getpwnam(lusername); 627*36518Skarels if (pwd == NULL) 62836453Skfall return(-1); 62936453Skfall 63036453Skfall /* XXX need to use something other than ruserok */ 63136453Skfall /* returns -1 for invalid authentication */ 63236453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 63336453Skfall } 634*36518Skarels #endif /* KERBEROS */ 635