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*36635Skarels static char sccsid[] = "@(#)rlogind.c 5.22.1.5 (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*36635Skarels * 36*36635Skarels * Automatic login protocol is done here, using login -f upon success, 37*36635Skarels * unless OLD_LOGIN is defined (then done in login, ala 4.2/4.3BSD). 3816369Skarels */ 3916369Skarels 406446Swnj #include <stdio.h> 41*36635Skarels #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*36635Skarels #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*36635Skarels 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*36635Skarels 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*36635Skarels syslog(LOG_ERR, "Couldn't get peer name of remote host: %m"); 107*36635Skarels 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*36635Skarels #ifndef OLD_LOGIN 13036631Skarels int authenticated = 0, hostok = 0; 131*36635Skarels char remotehost[2 * MAXHOSTNAMELEN + 1]; 132*36635Skarels #endif 13336633Skarels 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*36635Skarels hostok++; 15311345Ssam } 154*36635Skarels #ifndef OLD_LOGIN 155*36635Skarels else if (local_domain(hp->h_name)) { 156*36635Skarels /* 157*36635Skarels * If name returned by gethostbyaddr is in our domain, 158*36635Skarels * attempt to verify that we haven't been fooled by someone 159*36635Skarels * in a remote net; look up the name and check that this 160*36635Skarels * address corresponds to the name. 161*36635Skarels */ 162*36635Skarels strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); 163*36635Skarels remotehost[sizeof(remotehost) - 1] = 0; 164*36635Skarels hp = gethostbyname(remotehost); 165*36635Skarels if (hp) 166*36635Skarels for (; hp->h_addr_list[0]; hp->h_addr_list++) 167*36635Skarels if (!bcmp(hp->h_addr_list[0], (caddr_t)&fromp->sin_addr, 168*36635Skarels sizeof(fromp->sin_addr))) { 169*36635Skarels hostok++; 170*36635Skarels break; 171*36635Skarels } 17236633Skarels } else 173*36635Skarels hostok++; 17436633Skarels #endif 175*36635Skarels 17636631Skarels if (fromp->sin_family != AF_INET || 17736631Skarels fromp->sin_port >= IPPORT_RESERVED || 17836631Skarels fromp->sin_port < IPPORT_RESERVED/2) { 17936631Skarels syslog(LOG_NOTICE, "Connection from %s on illegal port", 18036631Skarels inet_ntoa(fromp->sin_addr)); 18136631Skarels fatal(f, "Permission denied"); 18236631Skarels } 18336632Skarels write(f, "", 1); 184*36635Skarels #ifndef OLD_LOGIN 18536632Skarels if (do_rlogin(hp->h_name) == 0) { 18636632Skarels if (hostok) 187*36635Skarels authenticated++; 18836632Skarels else 189*36635Skarels write(f, "rlogind: Host address mismatch.\r\n", 190*36635Skarels sizeof("rlogind: Host address mismatch.\r\n") - 1); 19136632Skarels } 192*36635Skarels #endif 19336609Skfall 1946446Swnj for (c = 'p'; c <= 's'; c++) { 1956446Swnj struct stat stb; 1966446Swnj line = "/dev/ptyXX"; 1976446Swnj line[strlen("/dev/pty")] = c; 1986446Swnj line[strlen("/dev/ptyp")] = '0'; 1996446Swnj if (stat(line, &stb) < 0) 2006446Swnj break; 2016446Swnj for (i = 0; i < 16; i++) { 20234424Sbostic line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; 20334424Sbostic p = open(line, O_RDWR); 2046446Swnj if (p > 0) 2056446Swnj goto gotpty; 2066446Swnj } 2076446Swnj } 20824723Smckusick fatal(f, "Out of ptys"); 2099242Ssam /*NOTREACHED*/ 2106446Swnj gotpty: 21124889Smckusick (void) ioctl(p, TIOCSWINSZ, &win); 21216227Skarels netf = f; 2136446Swnj line[strlen("/dev/")] = 't'; 21434424Sbostic t = open(line, O_RDWR); 21534424Sbostic if (t < 0) 21634424Sbostic fatalperror(f, line); 21734424Sbostic if (fchmod(t, 0)) 21834424Sbostic fatalperror(f, line); 21934424Sbostic (void)signal(SIGHUP, SIG_IGN); 22034424Sbostic vhangup(); 22134424Sbostic (void)signal(SIGHUP, SIG_DFL); 22234424Sbostic t = open(line, O_RDWR); 22334424Sbostic if (t < 0) 22434424Sbostic fatalperror(f, line); 22536453Skfall setup_term(t); 2266446Swnj #ifdef DEBUG 22734424Sbostic { 22834424Sbostic int tt = open("/dev/tty", O_RDWR); 22934424Sbostic if (tt > 0) { 23034424Sbostic (void)ioctl(tt, TIOCNOTTY, 0); 23134424Sbostic (void)close(tt); 23234424Sbostic } 2336446Swnj } 2346446Swnj #endif 2359242Ssam pid = fork(); 2369242Ssam if (pid < 0) 23734424Sbostic fatalperror(f, ""); 23818357Ssam if (pid == 0) { 23918357Ssam close(f), close(p); 24018357Ssam dup2(t, 0), dup2(t, 1), dup2(t, 2); 24116227Skarels close(t); 242*36635Skarels #ifdef OLD_LOGIN 243*36635Skarels execl("/bin/login", "login", "-r", hp->h_name, 0); 244*36635Skarels #else /* OLD_LOGIN */ 24536631Skarels if (authenticated) 246*36635Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 247*36635Skarels "-f", lusername, 0); 24836525Skfall else 249*36635Skarels execl("/bin/login", "login", "-p", "-h", hp->h_name, 250*36635Skarels lusername, 0); 251*36635Skarels #endif /* OLD_LOGIN */ 25234424Sbostic fatalperror(2, "/bin/login"); 25318357Ssam /*NOTREACHED*/ 25418357Ssam } 25518357Ssam close(t); 25636453Skfall 257*36635Skarels ioctl(f, FIONBIO, &on); 25818357Ssam ioctl(p, FIONBIO, &on); 25918357Ssam ioctl(p, TIOCPKT, &on); 26018357Ssam signal(SIGTSTP, SIG_IGN); 26118357Ssam signal(SIGCHLD, cleanup); 26224724Smckusick setpgrp(0, 0); 26318357Ssam protocol(f, p); 26430600Smckusick signal(SIGCHLD, SIG_IGN); 26518357Ssam cleanup(); 26618357Ssam } 2679242Ssam 26818357Ssam char magic[2] = { 0377, 0377 }; 26925423Skarels char oobdata[] = {TIOCPKT_WINDOW}; 27018357Ssam 27118357Ssam /* 27218357Ssam * Handle a "control" request (signaled by magic being present) 27318357Ssam * in the data stream. For now, we are only willing to handle 27418357Ssam * window size changes. 27518357Ssam */ 27618357Ssam control(pty, cp, n) 27718357Ssam int pty; 27818357Ssam char *cp; 27918357Ssam int n; 28018357Ssam { 28128705Smckusick struct winsize w; 28218357Ssam 28328705Smckusick if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 28418357Ssam return (0); 28525423Skarels oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 28628705Smckusick bcopy(cp+4, (char *)&w, sizeof(w)); 28728705Smckusick w.ws_row = ntohs(w.ws_row); 28828705Smckusick w.ws_col = ntohs(w.ws_col); 28928705Smckusick w.ws_xpixel = ntohs(w.ws_xpixel); 29028705Smckusick w.ws_ypixel = ntohs(w.ws_ypixel); 29128705Smckusick (void)ioctl(pty, TIOCSWINSZ, &w); 29228705Smckusick return (4+sizeof (w)); 29318357Ssam } 29418357Ssam 29518357Ssam /* 29618357Ssam * rlogin "protocol" machine. 29718357Ssam */ 29818357Ssam protocol(f, p) 29918357Ssam int f, p; 30018357Ssam { 30118357Ssam char pibuf[1024], fibuf[1024], *pbp, *fbp; 30218357Ssam register pcc = 0, fcc = 0; 30336517Skarels int cc, nfd, pmask, fmask; 30425740Skarels char cntl; 30518357Ssam 30618482Ssam /* 30718484Ssam * Must ignore SIGTTOU, otherwise we'll stop 30818484Ssam * when we try and set slave pty's window shape 30925423Skarels * (our controlling tty is the master pty). 31018482Ssam */ 31118484Ssam (void) signal(SIGTTOU, SIG_IGN); 31225423Skarels send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 31336517Skarels if (f > p) 31436517Skarels nfd = f + 1; 31536517Skarels else 31636517Skarels nfd = p + 1; 31736517Skarels fmask = 1 << f; 31836517Skarels pmask = 1 << p; 31918357Ssam for (;;) { 32025740Skarels int ibits, obits, ebits; 32118357Ssam 32225740Skarels ibits = 0; 32325740Skarels obits = 0; 32418357Ssam if (fcc) 32536517Skarels obits |= pmask; 32618357Ssam else 32736517Skarels ibits |= fmask; 32818357Ssam if (pcc >= 0) 32918357Ssam if (pcc) 33036517Skarels obits |= fmask; 3319242Ssam else 33236517Skarels ibits |= pmask; 33336517Skarels ebits = pmask; 33436517Skarels if (select(nfd, &ibits, obits ? &obits : (int *)NULL, 33536517Skarels &ebits, 0) < 0) { 33618357Ssam if (errno == EINTR) 3376446Swnj continue; 33834424Sbostic fatalperror(f, "select"); 33918357Ssam } 34025740Skarels if (ibits == 0 && obits == 0 && ebits == 0) { 34118357Ssam /* shouldn't happen... */ 34218357Ssam sleep(5); 34318357Ssam continue; 34418357Ssam } 34525740Skarels #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 34636517Skarels if (ebits & pmask) { 34725740Skarels cc = read(p, &cntl, 1); 34825740Skarels if (cc == 1 && pkcontrol(cntl)) { 34925740Skarels cntl |= oobdata[0]; 35025740Skarels send(f, &cntl, 1, MSG_OOB); 35125740Skarels if (cntl & TIOCPKT_FLUSHWRITE) { 35225740Skarels pcc = 0; 35336517Skarels ibits &= ~pmask; 35425740Skarels } 35525740Skarels } 35625740Skarels } 35736517Skarels if (ibits & fmask) { 358*36635Skarels fcc = read(f, fibuf, sizeof(fibuf)); 35918357Ssam if (fcc < 0 && errno == EWOULDBLOCK) 36018357Ssam fcc = 0; 36118357Ssam else { 36218357Ssam register char *cp; 36318357Ssam int left, n; 36418357Ssam 36518357Ssam if (fcc <= 0) 36616227Skarels break; 36718357Ssam fbp = fibuf; 36824723Smckusick 36918357Ssam top: 37025423Skarels for (cp = fibuf; cp < fibuf+fcc-1; cp++) 37118357Ssam if (cp[0] == magic[0] && 37218357Ssam cp[1] == magic[1]) { 37318357Ssam left = fcc - (cp-fibuf); 37418357Ssam n = control(p, cp, left); 37518357Ssam if (n) { 37618357Ssam left -= n; 37718357Ssam if (left > 0) 37825423Skarels bcopy(cp+n, cp, left); 37918357Ssam fcc -= n; 38018357Ssam goto top; /* n^2 */ 38125423Skarels } 38225423Skarels } 38336517Skarels obits |= pmask; /* try write */ 38425423Skarels } 38525423Skarels } 38624723Smckusick 38736517Skarels if ((obits & pmask) && fcc > 0) { 38825423Skarels cc = write(p, fbp, fcc); 38924723Smckusick if (cc > 0) { 39024723Smckusick fcc -= cc; 39124723Smckusick fbp += cc; 3926446Swnj } 39318357Ssam } 39424723Smckusick 39536517Skarels if (ibits & pmask) { 39618357Ssam pcc = read(p, pibuf, sizeof (pibuf)); 39718357Ssam pbp = pibuf; 39818357Ssam if (pcc < 0 && errno == EWOULDBLOCK) 39918357Ssam pcc = 0; 40018357Ssam else if (pcc <= 0) 40118357Ssam break; 40236517Skarels else if (pibuf[0] == 0) { 40318357Ssam pbp++, pcc--; 404*36635Skarels obits |= fmask; /* try a write */ 40536517Skarels } else { 40618357Ssam if (pkcontrol(pibuf[0])) { 40725423Skarels pibuf[0] |= oobdata[0]; 40818357Ssam send(f, &pibuf[0], 1, MSG_OOB); 40916227Skarels } 41018357Ssam pcc = 0; 4116446Swnj } 41218357Ssam } 41336517Skarels if ((obits & fmask) && pcc > 0) { 414*36635Skarels cc = write(f, pbp, pcc); 41525423Skarels if (cc < 0 && errno == EWOULDBLOCK) { 41625423Skarels /* also shouldn't happen */ 41725423Skarels sleep(5); 41825423Skarels continue; 41925423Skarels } 42018357Ssam if (cc > 0) { 42118357Ssam pcc -= cc; 42218357Ssam pbp += cc; 42318357Ssam } 4246446Swnj } 4256446Swnj } 4266446Swnj } 4276446Swnj 4286446Swnj cleanup() 4296446Swnj { 43035440Sbostic char *p; 43135440Sbostic 43235440Sbostic p = line + sizeof("/dev/") - 1; 43335440Sbostic if (logout(p)) 43435440Sbostic logwtmp(p, "", ""); 43535440Sbostic (void)chmod(line, 0666); 43635440Sbostic (void)chown(line, 0, 0); 43735440Sbostic *p = 'p'; 43835440Sbostic (void)chmod(line, 0666); 43935440Sbostic (void)chown(line, 0, 0); 44010192Ssam shutdown(netf, 2); 4416446Swnj exit(1); 4426446Swnj } 4436446Swnj 4449242Ssam fatal(f, msg) 4459242Ssam int f; 4469242Ssam char *msg; 4479242Ssam { 4489242Ssam char buf[BUFSIZ]; 4499242Ssam 4509242Ssam buf[0] = '\01'; /* error indicator */ 45113554Ssam (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg); 4529242Ssam (void) write(f, buf, strlen(buf)); 4539242Ssam exit(1); 4549242Ssam } 4559242Ssam 45634424Sbostic fatalperror(f, msg) 4579242Ssam int f; 4589242Ssam char *msg; 4599242Ssam { 4609242Ssam char buf[BUFSIZ]; 46116227Skarels extern int sys_nerr; 4629242Ssam extern char *sys_errlist[]; 4639242Ssam 46418357Ssam if ((unsigned)errno < sys_nerr) 46516227Skarels (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]); 46616227Skarels else 46716227Skarels (void) sprintf(buf, "%s: Error %d", msg, errno); 4689242Ssam fatal(f, buf); 4699242Ssam } 47036453Skfall 471*36635Skarels #ifndef OLD_LOGIN 47236453Skfall do_rlogin(host) 47336518Skarels char *host; 47436453Skfall { 47536453Skfall 47636518Skarels getstr(rusername, sizeof(rusername), "remuser too long"); 47736518Skarels getstr(lusername, sizeof(lusername), "locuser too long"); 47836518Skarels getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); 47936518Skarels 48036518Skarels if (getuid()) 48136453Skfall return(-1); 48236453Skfall pwd = getpwnam(lusername); 48336518Skarels if (pwd == NULL) 48436453Skfall return(-1); 48536453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 48636453Skfall } 48736453Skfall 48836453Skfall 48936518Skarels getstr(buf, cnt, errmsg) 49036518Skarels char *buf; 49136518Skarels int cnt; 49236518Skarels char *errmsg; 49336453Skfall { 49436518Skarels char c; 49536518Skarels 49636453Skfall do { 49736518Skarels if (read(0, &c, 1) != 1) 49836453Skfall exit(1); 49936518Skarels if (--cnt < 0) 50036518Skarels fatal(1, errmsg); 50136453Skfall *buf++ = c; 50236518Skarels } while (c != 0); 50336453Skfall } 50436453Skfall 50536518Skarels extern char **environ; 50636453Skfall 507*36635Skarels char *speeds[] = { 508*36635Skarels "0", "50", "75", "110", "134", "150", "200", "300", "600", 509*36635Skarels "1200", "1800", "2400", "4800", "9600", "19200", "38400", 510*36635Skarels }; 511*36635Skarels #define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) 512*36635Skarels 51336519Skarels setup_term(fd) 51436519Skarels int fd; 51536519Skarels { 516*36635Skarels register char *cp = index(term, '/'), **cpp; 517*36635Skarels struct sgttyb sgttyb; 51836519Skarels char *speed; 51936519Skarels 520*36635Skarels (void)ioctl(fd, TIOCGETP, &sgttyb); 52136519Skarels if (cp) { 52236519Skarels *cp++ = '\0'; 52336519Skarels speed = cp; 52436519Skarels cp = index(speed, '/'); 52536519Skarels if (cp) 52636519Skarels *cp++ = '\0'; 527*36635Skarels for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 528*36635Skarels if (strcmp(*cpp, speed) == 0) { 529*36635Skarels sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds; 530*36635Skarels break; 531*36635Skarels } 53236519Skarels } 533*36635Skarels sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; 534*36635Skarels (void)ioctl(fd, TIOCSETP, &sgttyb); 53536519Skarels 53636519Skarels env[0] = term; 53736519Skarels env[1] = 0; 53836519Skarels environ = env; 53936519Skarels } 54036609Skfall 54136609Skfall /* 54236631Skarels * Check whether host h is in our local domain, 54336631Skarels * as determined by the part of the name following 54436631Skarels * the first '.' in its name and in ours. 54536631Skarels * If either name is unqualified (contains no '.'), 54636631Skarels * assume that the host is local, as it will be 54736631Skarels * interpreted as such. 54836631Skarels */ 54936631Skarels local_domain(h) 55036631Skarels char *h; 55136625Skfall { 55236631Skarels char localhost[MAXHOSTNAMELEN]; 55336631Skarels char *p1, *p2 = index(h, '.'); 55436631Skarels 55536631Skarels (void) gethostname(localhost, sizeof(localhost)); 55636631Skarels p1 = index(localhost, '.'); 55736631Skarels if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) 55836625Skfall return(1); 55936625Skfall return(0); 56036625Skfall } 561*36635Skarels #endif /* OLD_LOGIN */ 562