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*36632Skarels static char sccsid[] = "@(#)rlogind.c 5.22.1.4 (Berkeley) 01/25/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*36632Skarels * 36*36632Skarels * Automatic login protocol is done here, using login -f upon success, 37*36632Skarels * unless OLD_LOGIN is defined (then done in login, ala 4.2/4.3BSD). 3816369Skarels */ 3916369Skarels 406446Swnj #include <stdio.h> 41*36632Skarels #include <sys/param.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*36632Skarels #include <sgtty.h> 536446Swnj #include <stdio.h> 548380Ssam #include <netdb.h> 5517187Sralph #include <syslog.h> 5618357Ssam #include <strings.h> 576446Swnj 5836518Skarels #ifndef TIOCPKT_WINDOW 5936518Skarels #define TIOCPKT_WINDOW 0x80 6036518Skarels #endif 6136518Skarels 6236518Skarels char *env[2]; 6336518Skarels #define NMAX 30 6436517Skarels char lusername[NMAX+1], rusername[NMAX+1]; 6536517Skarels static char term[64] = "TERM="; 6636517Skarels #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ 6736517Skarels int keepalive = 1; 6836453Skfall 6936453Skfall #define SUPERUSER(pwd) ((pwd)->pw_uid == 0) 7036453Skfall 7134424Sbostic extern int errno; 7210417Ssam int reapchild(); 7336453Skfall struct passwd *getpwnam(), *pwd; 7424723Smckusick char *malloc(); 7516369Skarels 766446Swnj main(argc, argv) 776446Swnj int argc; 786446Swnj char **argv; 796446Swnj { 8036319Sbostic extern int opterr, optind, _check_rhosts_file; 8136319Sbostic int ch; 8234424Sbostic int on = 1, fromlen; 836446Swnj struct sockaddr_in from; 846446Swnj 8536625Skfall openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); 8636319Sbostic 8736319Sbostic opterr = 0; 88*36632Skarels while ((ch = getopt(argc, argv, "ln")) != EOF) 8936517Skarels switch (ch) { 9036319Sbostic case 'l': 9136319Sbostic _check_rhosts_file = 0; 9236319Sbostic break; 9336517Skarels case 'n': 9436517Skarels keepalive = 0; 9536517Skarels break; 9636319Sbostic case '?': 9736319Sbostic default: 98*36632Skarels syslog(LOG_ERR, "usage: rlogind [-l] [-n]"); 9936319Sbostic break; 10036319Sbostic } 10136319Sbostic argc -= optind; 10236319Sbostic argv += optind; 10336319Sbostic 10416369Skarels fromlen = sizeof (from); 10516369Skarels if (getpeername(0, &from, &fromlen) < 0) { 106*36632Skarels syslog(LOG_ERR, "Couldn't get peer name of remote host: %m"); 107*36632Skarels fatalperror("Can't get peer name of host"); 1088380Ssam } 10936517Skarels if (keepalive && 11036517Skarels setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) 11117187Sralph syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 11216369Skarels doit(0, &from); 1136446Swnj } 1146446Swnj 1156446Swnj int child; 1166446Swnj int cleanup(); 1176446Swnj int netf; 1186446Swnj char *line; 11924724Smckusick extern char *inet_ntoa(); 1206446Swnj 12124889Smckusick struct winsize win = { 0, 0, 0, 0 }; 12224723Smckusick 12324889Smckusick 1246446Swnj doit(f, fromp) 1256446Swnj int f; 1266446Swnj struct sockaddr_in *fromp; 1276446Swnj { 12818357Ssam int i, p, t, pid, on = 1; 129*36632Skarels #ifndef OLD_LOGIN 13036631Skarels int authenticated = 0, hostok = 0; 131*36632Skarels char remotehost[2 * MAXHOSTNAMELEN + 1]; 132*36632Skarels #endif 13318357Ssam register struct hostent *hp; 13424724Smckusick struct hostent hostent; 1358380Ssam char c; 1366446Swnj 1376446Swnj alarm(60); 1386446Swnj read(f, &c, 1); 1396446Swnj if (c != 0) 1406446Swnj exit(1); 14136453Skfall 1426446Swnj alarm(0); 14316227Skarels fromp->sin_port = ntohs((u_short)fromp->sin_port); 1448380Ssam hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), 1458380Ssam fromp->sin_family); 14611345Ssam if (hp == 0) { 14724724Smckusick /* 14824724Smckusick * Only the name is used below. 14924724Smckusick */ 15024724Smckusick hp = &hostent; 15124724Smckusick hp->h_name = inet_ntoa(fromp->sin_addr); 152*36632Skarels #ifndef OLD_LOGIN 15336631Skarels } else if (local_domain(hp->h_name)) { 15436631Skarels /* 15536631Skarels * If name returned by gethostbyaddr is in our domain, 15636631Skarels * attempt to verify that we haven't been fooled by someone 15736631Skarels * in a remote net; look up the name and check that this 15836631Skarels * address corresponds to the name. 15936631Skarels */ 16036631Skarels strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); 16136631Skarels remotehost[sizeof(remotehost) - 1] = 0; 16236631Skarels hp = gethostbyname(remotehost); 16336631Skarels if (hp) 16436631Skarels for (; hp->h_addr_list[0]; hp->h_addr_list++) { 16536631Skarels if (!bcmp(hp->h_addr_list[0], (caddr_t)&fromp->sin_addr, 16636631Skarels sizeof(fromp->sin_addr))) { 16736631Skarels hostok++; 16836631Skarels break; 16936625Skfall } 17036625Skfall } 171*36632Skarels #endif 17211345Ssam } 17336453Skfall 17436631Skarels if (fromp->sin_family != AF_INET || 17536631Skarels fromp->sin_port >= IPPORT_RESERVED || 17636631Skarels fromp->sin_port < IPPORT_RESERVED/2) { 17736631Skarels syslog(LOG_NOTICE, "Connection from %s on illegal port", 17836631Skarels inet_ntoa(fromp->sin_addr)); 17936631Skarels fatal(f, "Permission denied"); 18036631Skarels } 181*36632Skarels write(f, "", 1); 182*36632Skarels #ifndef OLD_LOGIN 183*36632Skarels if (do_rlogin(hp->h_name) == 0) { 184*36632Skarels if (hostok) 185*36632Skarels authenticated++; 186*36632Skarels else 187*36632Skarels write(f, "rlogind: Host address mismatch.\r\n", 188*36632Skarels sizeof("rlogind: Host address mismatch.\r\n") - 1); 189*36632Skarels } 190*36632Skarels #endif 19136609Skfall 1926446Swnj for (c = 'p'; c <= 's'; c++) { 1936446Swnj struct stat stb; 1946446Swnj line = "/dev/ptyXX"; 1956446Swnj line[strlen("/dev/pty")] = c; 1966446Swnj line[strlen("/dev/ptyp")] = '0'; 1976446Swnj if (stat(line, &stb) < 0) 1986446Swnj break; 1996446Swnj for (i = 0; i < 16; i++) { 20034424Sbostic line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; 20134424Sbostic p = open(line, O_RDWR); 2026446Swnj if (p > 0) 2036446Swnj goto gotpty; 2046446Swnj } 2056446Swnj } 20624723Smckusick fatal(f, "Out of ptys"); 2079242Ssam /*NOTREACHED*/ 2086446Swnj gotpty: 20924889Smckusick (void) ioctl(p, TIOCSWINSZ, &win); 21016227Skarels netf = f; 2116446Swnj line[strlen("/dev/")] = 't'; 21234424Sbostic t = open(line, O_RDWR); 21334424Sbostic if (t < 0) 21434424Sbostic fatalperror(f, line); 21534424Sbostic if (fchmod(t, 0)) 21634424Sbostic fatalperror(f, line); 21734424Sbostic (void)signal(SIGHUP, SIG_IGN); 21834424Sbostic vhangup(); 21934424Sbostic (void)signal(SIGHUP, SIG_DFL); 22034424Sbostic t = open(line, O_RDWR); 22134424Sbostic if (t < 0) 22234424Sbostic fatalperror(f, line); 22336453Skfall setup_term(t); 2246446Swnj #ifdef DEBUG 22534424Sbostic { 22634424Sbostic int tt = open("/dev/tty", O_RDWR); 22734424Sbostic if (tt > 0) { 22834424Sbostic (void)ioctl(tt, TIOCNOTTY, 0); 22934424Sbostic (void)close(tt); 23034424Sbostic } 2316446Swnj } 2326446Swnj #endif 2339242Ssam pid = fork(); 2349242Ssam if (pid < 0) 23534424Sbostic fatalperror(f, ""); 23618357Ssam if (pid == 0) { 23718357Ssam close(f), close(p); 23818357Ssam dup2(t, 0), dup2(t, 1), dup2(t, 2); 23916227Skarels close(t); 240*36632Skarels #ifdef OLD_LOGIN 241*36632Skarels execl("/bin/login", "login", "-r", hp->h_name, 0); 242*36632Skarels #else /* OLD_LOGIN */ 24336631Skarels if (authenticated) 244*36632Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 245*36632Skarels "-f", lusername, 0); 24636525Skfall else 247*36632Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 248*36632Skarels lusername, 0); 249*36632Skarels #endif /* OLD_LOGIN */ 25034424Sbostic fatalperror(2, "/bin/login"); 25118357Ssam /*NOTREACHED*/ 25218357Ssam } 25318357Ssam close(t); 25436453Skfall 255*36632Skarels ioctl(f, FIONBIO, &on); 25618357Ssam ioctl(p, FIONBIO, &on); 25718357Ssam ioctl(p, TIOCPKT, &on); 25818357Ssam signal(SIGTSTP, SIG_IGN); 25918357Ssam signal(SIGCHLD, cleanup); 26024724Smckusick setpgrp(0, 0); 26118357Ssam protocol(f, p); 26230600Smckusick signal(SIGCHLD, SIG_IGN); 26318357Ssam cleanup(); 26418357Ssam } 2659242Ssam 26618357Ssam char magic[2] = { 0377, 0377 }; 26725423Skarels char oobdata[] = {TIOCPKT_WINDOW}; 26818357Ssam 26918357Ssam /* 27018357Ssam * Handle a "control" request (signaled by magic being present) 27118357Ssam * in the data stream. For now, we are only willing to handle 27218357Ssam * window size changes. 27318357Ssam */ 27418357Ssam control(pty, cp, n) 27518357Ssam int pty; 27618357Ssam char *cp; 27718357Ssam int n; 27818357Ssam { 27928705Smckusick struct winsize w; 28018357Ssam 28128705Smckusick if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 28218357Ssam return (0); 28325423Skarels oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 28428705Smckusick bcopy(cp+4, (char *)&w, sizeof(w)); 28528705Smckusick w.ws_row = ntohs(w.ws_row); 28628705Smckusick w.ws_col = ntohs(w.ws_col); 28728705Smckusick w.ws_xpixel = ntohs(w.ws_xpixel); 28828705Smckusick w.ws_ypixel = ntohs(w.ws_ypixel); 28928705Smckusick (void)ioctl(pty, TIOCSWINSZ, &w); 29028705Smckusick return (4+sizeof (w)); 29118357Ssam } 29218357Ssam 29318357Ssam /* 29418357Ssam * rlogin "protocol" machine. 29518357Ssam */ 29618357Ssam protocol(f, p) 29718357Ssam int f, p; 29818357Ssam { 29918357Ssam char pibuf[1024], fibuf[1024], *pbp, *fbp; 30018357Ssam register pcc = 0, fcc = 0; 30136517Skarels int cc, nfd, pmask, fmask; 30225740Skarels char cntl; 30318357Ssam 30418482Ssam /* 30518484Ssam * Must ignore SIGTTOU, otherwise we'll stop 30618484Ssam * when we try and set slave pty's window shape 30725423Skarels * (our controlling tty is the master pty). 30818482Ssam */ 30918484Ssam (void) signal(SIGTTOU, SIG_IGN); 31025423Skarels send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 31136517Skarels if (f > p) 31236517Skarels nfd = f + 1; 31336517Skarels else 31436517Skarels nfd = p + 1; 31536517Skarels fmask = 1 << f; 31636517Skarels pmask = 1 << p; 31718357Ssam for (;;) { 31825740Skarels int ibits, obits, ebits; 31918357Ssam 32025740Skarels ibits = 0; 32125740Skarels obits = 0; 32218357Ssam if (fcc) 32336517Skarels obits |= pmask; 32418357Ssam else 32536517Skarels ibits |= fmask; 32618357Ssam if (pcc >= 0) 32718357Ssam if (pcc) 32836517Skarels obits |= fmask; 3299242Ssam else 33036517Skarels ibits |= pmask; 33136517Skarels ebits = pmask; 33236517Skarels if (select(nfd, &ibits, obits ? &obits : (int *)NULL, 33336517Skarels &ebits, 0) < 0) { 33418357Ssam if (errno == EINTR) 3356446Swnj continue; 33634424Sbostic fatalperror(f, "select"); 33718357Ssam } 33825740Skarels if (ibits == 0 && obits == 0 && ebits == 0) { 33918357Ssam /* shouldn't happen... */ 34018357Ssam sleep(5); 34118357Ssam continue; 34218357Ssam } 34325740Skarels #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 34436517Skarels if (ebits & pmask) { 34525740Skarels cc = read(p, &cntl, 1); 34625740Skarels if (cc == 1 && pkcontrol(cntl)) { 34725740Skarels cntl |= oobdata[0]; 34825740Skarels send(f, &cntl, 1, MSG_OOB); 34925740Skarels if (cntl & TIOCPKT_FLUSHWRITE) { 35025740Skarels pcc = 0; 35136517Skarels ibits &= ~pmask; 35225740Skarels } 35325740Skarels } 35425740Skarels } 35536517Skarels if (ibits & fmask) { 356*36632Skarels fcc = read(f, fibuf, sizeof(fibuf)); 35718357Ssam if (fcc < 0 && errno == EWOULDBLOCK) 35818357Ssam fcc = 0; 35918357Ssam else { 36018357Ssam register char *cp; 36118357Ssam int left, n; 36218357Ssam 36318357Ssam if (fcc <= 0) 36416227Skarels break; 36518357Ssam fbp = fibuf; 36624723Smckusick 36718357Ssam top: 36825423Skarels for (cp = fibuf; cp < fibuf+fcc-1; cp++) 36918357Ssam if (cp[0] == magic[0] && 37018357Ssam cp[1] == magic[1]) { 37118357Ssam left = fcc - (cp-fibuf); 37218357Ssam n = control(p, cp, left); 37318357Ssam if (n) { 37418357Ssam left -= n; 37518357Ssam if (left > 0) 37625423Skarels bcopy(cp+n, cp, left); 37718357Ssam fcc -= n; 37818357Ssam goto top; /* n^2 */ 37925423Skarels } 38025423Skarels } 38136517Skarels obits |= pmask; /* try write */ 38225423Skarels } 38325423Skarels } 38424723Smckusick 38536517Skarels if ((obits & pmask) && fcc > 0) { 38625423Skarels cc = write(p, fbp, fcc); 38724723Smckusick if (cc > 0) { 38824723Smckusick fcc -= cc; 38924723Smckusick fbp += cc; 3906446Swnj } 39118357Ssam } 39224723Smckusick 39336517Skarels if (ibits & pmask) { 39418357Ssam pcc = read(p, pibuf, sizeof (pibuf)); 39518357Ssam pbp = pibuf; 39618357Ssam if (pcc < 0 && errno == EWOULDBLOCK) 39718357Ssam pcc = 0; 39818357Ssam else if (pcc <= 0) 39918357Ssam break; 40036517Skarels else if (pibuf[0] == 0) { 40118357Ssam pbp++, pcc--; 402*36632Skarels obits |= fmask; /* try a write */ 40336517Skarels } else { 40418357Ssam if (pkcontrol(pibuf[0])) { 40525423Skarels pibuf[0] |= oobdata[0]; 40618357Ssam send(f, &pibuf[0], 1, MSG_OOB); 40716227Skarels } 40818357Ssam pcc = 0; 4096446Swnj } 41018357Ssam } 41136517Skarels if ((obits & fmask) && pcc > 0) { 412*36632Skarels cc = write(f, pbp, pcc); 41325423Skarels if (cc < 0 && errno == EWOULDBLOCK) { 41425423Skarels /* also shouldn't happen */ 41525423Skarels sleep(5); 41625423Skarels continue; 41725423Skarels } 41818357Ssam if (cc > 0) { 41918357Ssam pcc -= cc; 42018357Ssam pbp += cc; 42118357Ssam } 4226446Swnj } 4236446Swnj } 4246446Swnj } 4256446Swnj 4266446Swnj cleanup() 4276446Swnj { 42835440Sbostic char *p; 42935440Sbostic 43035440Sbostic p = line + sizeof("/dev/") - 1; 43135440Sbostic if (logout(p)) 43235440Sbostic logwtmp(p, "", ""); 43335440Sbostic (void)chmod(line, 0666); 43435440Sbostic (void)chown(line, 0, 0); 43535440Sbostic *p = 'p'; 43635440Sbostic (void)chmod(line, 0666); 43735440Sbostic (void)chown(line, 0, 0); 43810192Ssam shutdown(netf, 2); 4396446Swnj exit(1); 4406446Swnj } 4416446Swnj 4429242Ssam fatal(f, msg) 4439242Ssam int f; 4449242Ssam char *msg; 4459242Ssam { 4469242Ssam char buf[BUFSIZ]; 4479242Ssam 4489242Ssam buf[0] = '\01'; /* error indicator */ 44913554Ssam (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg); 4509242Ssam (void) write(f, buf, strlen(buf)); 4519242Ssam exit(1); 4529242Ssam } 4539242Ssam 45434424Sbostic fatalperror(f, msg) 4559242Ssam int f; 4569242Ssam char *msg; 4579242Ssam { 4589242Ssam char buf[BUFSIZ]; 45916227Skarels extern int sys_nerr; 4609242Ssam extern char *sys_errlist[]; 4619242Ssam 46218357Ssam if ((unsigned)errno < sys_nerr) 46316227Skarels (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]); 46416227Skarels else 46516227Skarels (void) sprintf(buf, "%s: Error %d", msg, errno); 4669242Ssam fatal(f, buf); 4679242Ssam } 46836453Skfall 469*36632Skarels #ifndef OLD_LOGIN 47036453Skfall do_rlogin(host) 47136518Skarels char *host; 47236453Skfall { 47336453Skfall 47436518Skarels getstr(rusername, sizeof(rusername), "remuser too long"); 47536518Skarels getstr(lusername, sizeof(lusername), "locuser too long"); 47636518Skarels getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); 47736518Skarels 47836518Skarels if (getuid()) 47936453Skfall return(-1); 48036453Skfall pwd = getpwnam(lusername); 48136518Skarels if (pwd == NULL) 48236453Skfall return(-1); 48336453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 48436453Skfall } 48536453Skfall 48636453Skfall 48736518Skarels getstr(buf, cnt, errmsg) 48836518Skarels char *buf; 48936518Skarels int cnt; 49036518Skarels char *errmsg; 49136453Skfall { 49236518Skarels char c; 49336518Skarels 49436453Skfall do { 49536518Skarels if (read(0, &c, 1) != 1) 49636453Skfall exit(1); 49736518Skarels if (--cnt < 0) 49836518Skarels fatal(1, errmsg); 49936453Skfall *buf++ = c; 50036518Skarels } while (c != 0); 50136453Skfall } 50236453Skfall 50336518Skarels extern char **environ; 50436453Skfall 505*36632Skarels char *speeds[] = { 506*36632Skarels "0", "50", "75", "110", "134", "150", "200", "300", "600", 507*36632Skarels "1200", "1800", "2400", "4800", "9600", "19200", "38400", 508*36632Skarels }; 509*36632Skarels #define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) 510*36632Skarels 51136519Skarels setup_term(fd) 51236519Skarels int fd; 51336519Skarels { 514*36632Skarels register char *cp = index(term, '/'), **cpp; 515*36632Skarels struct sgttyb sgttyb; 51636519Skarels char *speed; 51736519Skarels 518*36632Skarels (void)ioctl(fd, TIOCGETP, &sgttyb); 51936519Skarels if (cp) { 52036519Skarels *cp++ = '\0'; 52136519Skarels speed = cp; 52236519Skarels cp = index(speed, '/'); 52336519Skarels if (cp) 52436519Skarels *cp++ = '\0'; 525*36632Skarels for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 526*36632Skarels if (strcmp(*cpp, speed) == 0) { 527*36632Skarels sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds; 528*36632Skarels break; 529*36632Skarels } 53036519Skarels } 531*36632Skarels sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; 532*36632Skarels (void)ioctl(fd, TIOCSETP, &sgttyb); 53336519Skarels 53436519Skarels env[0] = term; 53536519Skarels env[1] = 0; 53636519Skarels environ = env; 53736519Skarels } 53836609Skfall 53936609Skfall /* 54036631Skarels * Check whether host h is in our local domain, 54136631Skarels * as determined by the part of the name following 54236631Skarels * the first '.' in its name and in ours. 54336631Skarels * If either name is unqualified (contains no '.'), 54436631Skarels * assume that the host is local, as it will be 54536631Skarels * interpreted as such. 54636631Skarels */ 54736631Skarels local_domain(h) 54836631Skarels char *h; 54936625Skfall { 55036631Skarels char localhost[MAXHOSTNAMELEN]; 55136631Skarels char *p1, *p2 = index(h, '.'); 55236631Skarels 55336631Skarels (void) gethostname(localhost, sizeof(localhost)); 55436631Skarels p1 = index(localhost, '.'); 55536631Skarels if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) 55636625Skfall return(1); 55736625Skfall return(0); 55836625Skfall } 559*36632Skarels #endif /* OLD_LOGIN */ 560