17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California.
87c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement
97c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
107c478bd9Sstevel@tonic-gate */
117c478bd9Sstevel@tonic-gate
127c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
137c478bd9Sstevel@tonic-gate
147c478bd9Sstevel@tonic-gate #include <stdio.h>
157c478bd9Sstevel@tonic-gate #include <ctype.h>
167c478bd9Sstevel@tonic-gate #include <pwd.h>
177c478bd9Sstevel@tonic-gate #include <sys/param.h>
187c478bd9Sstevel@tonic-gate #include <sys/file.h>
197c478bd9Sstevel@tonic-gate #include <sys/signal.h>
207c478bd9Sstevel@tonic-gate #include <sys/socket.h>
217c478bd9Sstevel@tonic-gate #include <sys/stat.h>
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate #include <netinet/in.h>
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate #include <netdb.h>
267c478bd9Sstevel@tonic-gate #include <errno.h>
277c478bd9Sstevel@tonic-gate
28*5d54f3d8Smuffin #include <strings.h>
29*5d54f3d8Smuffin
307c478bd9Sstevel@tonic-gate static char *domain;
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate int
rcmd(char ** ahost,unsigned short rport,const char * locuser,const char * remuser,const char * cmd,int * fd2p)337c478bd9Sstevel@tonic-gate rcmd(
347c478bd9Sstevel@tonic-gate char **ahost,
357c478bd9Sstevel@tonic-gate unsigned short rport,
367c478bd9Sstevel@tonic-gate const char *locuser,
377c478bd9Sstevel@tonic-gate const char *remuser,
387c478bd9Sstevel@tonic-gate const char *cmd,
397c478bd9Sstevel@tonic-gate int *fd2p)
407c478bd9Sstevel@tonic-gate {
417c478bd9Sstevel@tonic-gate int s, timo = 1, pid, oldmask, retval;
427c478bd9Sstevel@tonic-gate struct sockaddr_in sin, from;
437c478bd9Sstevel@tonic-gate char c;
447c478bd9Sstevel@tonic-gate int lport = IPPORT_RESERVED - 1;
457c478bd9Sstevel@tonic-gate struct hostent *hp;
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate pid = getpid();
487c478bd9Sstevel@tonic-gate hp = gethostbyname(*ahost);
497c478bd9Sstevel@tonic-gate if (hp == 0) {
507c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: unknown host\n", *ahost);
517c478bd9Sstevel@tonic-gate return (-1);
527c478bd9Sstevel@tonic-gate }
537c478bd9Sstevel@tonic-gate *ahost = hp->h_name;
547c478bd9Sstevel@tonic-gate oldmask = sigblock(sigmask(SIGURG));
557c478bd9Sstevel@tonic-gate for (;;) {
567c478bd9Sstevel@tonic-gate s = rresvport(&lport);
577c478bd9Sstevel@tonic-gate if (s < 0) {
587c478bd9Sstevel@tonic-gate if (errno == EAGAIN)
597c478bd9Sstevel@tonic-gate fprintf(stderr, "socket: All ports in use\n");
607c478bd9Sstevel@tonic-gate else
617c478bd9Sstevel@tonic-gate perror("rcmd: socket");
627c478bd9Sstevel@tonic-gate sigsetmask(oldmask);
637c478bd9Sstevel@tonic-gate return (-1);
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate fcntl(s, F_SETOWN, pid);
667c478bd9Sstevel@tonic-gate sin.sin_family = hp->h_addrtype;
677c478bd9Sstevel@tonic-gate bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
687c478bd9Sstevel@tonic-gate sin.sin_port = rport;
697c478bd9Sstevel@tonic-gate if (connect(s, &sin, sizeof (sin)) >= 0)
707c478bd9Sstevel@tonic-gate break;
717c478bd9Sstevel@tonic-gate (void) close(s);
727c478bd9Sstevel@tonic-gate if (errno == EADDRINUSE) {
737c478bd9Sstevel@tonic-gate lport--;
747c478bd9Sstevel@tonic-gate continue;
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate if (errno == ECONNREFUSED && timo <= 16) {
777c478bd9Sstevel@tonic-gate sleep(timo);
787c478bd9Sstevel@tonic-gate timo *= 2;
797c478bd9Sstevel@tonic-gate continue;
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate if (hp->h_addr_list[1] != NULL) {
827c478bd9Sstevel@tonic-gate int oerrno = errno;
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate fprintf(stderr,
857c478bd9Sstevel@tonic-gate "connect to address %s: ", inet_ntoa(sin.sin_addr));
867c478bd9Sstevel@tonic-gate errno = oerrno;
877c478bd9Sstevel@tonic-gate perror(0);
887c478bd9Sstevel@tonic-gate hp->h_addr_list++;
897c478bd9Sstevel@tonic-gate bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
907c478bd9Sstevel@tonic-gate hp->h_length);
917c478bd9Sstevel@tonic-gate fprintf(stderr, "Trying %s...\n",
927c478bd9Sstevel@tonic-gate inet_ntoa(sin.sin_addr));
937c478bd9Sstevel@tonic-gate continue;
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate perror(hp->h_name);
967c478bd9Sstevel@tonic-gate sigsetmask(oldmask);
977c478bd9Sstevel@tonic-gate return (-1);
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate lport--;
1007c478bd9Sstevel@tonic-gate if (fd2p == 0) {
1017c478bd9Sstevel@tonic-gate write(s, "", 1);
1027c478bd9Sstevel@tonic-gate lport = 0;
1037c478bd9Sstevel@tonic-gate } else {
1047c478bd9Sstevel@tonic-gate char num[8];
1057c478bd9Sstevel@tonic-gate int s2 = rresvport(&lport), s3;
1067c478bd9Sstevel@tonic-gate int len = sizeof (from);
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate if (s2 < 0)
1097c478bd9Sstevel@tonic-gate goto bad;
1107c478bd9Sstevel@tonic-gate listen(s2, 1);
1117c478bd9Sstevel@tonic-gate (void) sprintf(num, "%d", lport);
1127c478bd9Sstevel@tonic-gate if (write(s, num, strlen(num)+1) != strlen(num)+1) {
1137c478bd9Sstevel@tonic-gate perror("write: setting up stderr");
1147c478bd9Sstevel@tonic-gate (void) close(s2);
1157c478bd9Sstevel@tonic-gate goto bad;
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate s3 = accept(s2, &from, &len);
1187c478bd9Sstevel@tonic-gate (void) close(s2);
1197c478bd9Sstevel@tonic-gate if (s3 < 0) {
1207c478bd9Sstevel@tonic-gate perror("accept");
1217c478bd9Sstevel@tonic-gate lport = 0;
1227c478bd9Sstevel@tonic-gate goto bad;
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate *fd2p = s3;
1257c478bd9Sstevel@tonic-gate from.sin_port = ntohs((u_short)from.sin_port);
1267c478bd9Sstevel@tonic-gate if (from.sin_family != AF_INET ||
1277c478bd9Sstevel@tonic-gate from.sin_port >= IPPORT_RESERVED) {
1287c478bd9Sstevel@tonic-gate fprintf(stderr,
1297c478bd9Sstevel@tonic-gate "socket: protocol failure in circuit setup.\n");
1307c478bd9Sstevel@tonic-gate goto bad2;
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate (void) write(s, locuser, strlen(locuser)+1);
1347c478bd9Sstevel@tonic-gate (void) write(s, remuser, strlen(remuser)+1);
1357c478bd9Sstevel@tonic-gate (void) write(s, cmd, strlen(cmd)+1);
1367c478bd9Sstevel@tonic-gate retval = read(s, &c, 1);
1377c478bd9Sstevel@tonic-gate if (retval != 1) {
1387c478bd9Sstevel@tonic-gate if (retval == 0) {
1397c478bd9Sstevel@tonic-gate fprintf(stderr,
1407c478bd9Sstevel@tonic-gate "Protocol error, %s closed connection\n", *ahost);
1417c478bd9Sstevel@tonic-gate } else if (retval < 0) {
1427c478bd9Sstevel@tonic-gate perror(*ahost);
1437c478bd9Sstevel@tonic-gate } else {
1447c478bd9Sstevel@tonic-gate fprintf(stderr,
1457c478bd9Sstevel@tonic-gate "Protocol error, %s sent %d bytes\n", *ahost, retval);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate goto bad2;
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate if (c != 0) {
1507c478bd9Sstevel@tonic-gate while (read(s, &c, 1) == 1) {
1517c478bd9Sstevel@tonic-gate (void) write(2, &c, 1);
1527c478bd9Sstevel@tonic-gate if (c == '\n')
1537c478bd9Sstevel@tonic-gate break;
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate goto bad2;
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate sigsetmask(oldmask);
1587c478bd9Sstevel@tonic-gate return (s);
1597c478bd9Sstevel@tonic-gate bad2:
1607c478bd9Sstevel@tonic-gate if (lport)
1617c478bd9Sstevel@tonic-gate (void) close(*fd2p);
1627c478bd9Sstevel@tonic-gate bad:
1637c478bd9Sstevel@tonic-gate (void) close(s);
1647c478bd9Sstevel@tonic-gate sigsetmask(oldmask);
1657c478bd9Sstevel@tonic-gate return (-1);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate int
rresvport(int * alport)169*5d54f3d8Smuffin rresvport(int *alport)
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate struct sockaddr_in sin;
1727c478bd9Sstevel@tonic-gate int s;
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate sin.sin_family = AF_INET;
1757c478bd9Sstevel@tonic-gate sin.sin_addr.s_addr = INADDR_ANY;
1767c478bd9Sstevel@tonic-gate s = socket(AF_INET, SOCK_STREAM, 0);
1777c478bd9Sstevel@tonic-gate if (s < 0)
1787c478bd9Sstevel@tonic-gate return (-1);
1797c478bd9Sstevel@tonic-gate for (;;) {
1807c478bd9Sstevel@tonic-gate sin.sin_port = htons((u_short)*alport);
1817c478bd9Sstevel@tonic-gate if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
1827c478bd9Sstevel@tonic-gate return (s);
1837c478bd9Sstevel@tonic-gate if (errno != EADDRINUSE) {
1847c478bd9Sstevel@tonic-gate (void) close(s);
1857c478bd9Sstevel@tonic-gate return (-1);
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate (*alport)--;
1887c478bd9Sstevel@tonic-gate if (*alport == IPPORT_RESERVED/2) {
1897c478bd9Sstevel@tonic-gate (void) close(s);
1907c478bd9Sstevel@tonic-gate errno = EAGAIN; /* close */
1917c478bd9Sstevel@tonic-gate return (-1);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate int
ruserok(const char * rhost,int superuser,const char * ruser,const char * luser)1977c478bd9Sstevel@tonic-gate ruserok(
1987c478bd9Sstevel@tonic-gate const char *rhost,
1997c478bd9Sstevel@tonic-gate int superuser,
2007c478bd9Sstevel@tonic-gate const char *ruser,
2017c478bd9Sstevel@tonic-gate const char *luser)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate FILE *hostf;
2047c478bd9Sstevel@tonic-gate char fhost[MAXHOSTNAMELEN];
205*5d54f3d8Smuffin const char *sp;
206*5d54f3d8Smuffin char *p;
2077c478bd9Sstevel@tonic-gate int baselen = -1;
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate struct stat sbuf;
2107c478bd9Sstevel@tonic-gate struct passwd *pwd;
2117c478bd9Sstevel@tonic-gate char pbuf[MAXPATHLEN];
2127c478bd9Sstevel@tonic-gate int euid = -1;
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate sp = rhost;
2157c478bd9Sstevel@tonic-gate p = fhost;
2167c478bd9Sstevel@tonic-gate while (*sp) {
2177c478bd9Sstevel@tonic-gate if (*sp == '.') {
2187c478bd9Sstevel@tonic-gate if (baselen == -1)
2197c478bd9Sstevel@tonic-gate baselen = sp - rhost;
2207c478bd9Sstevel@tonic-gate *p++ = *sp++;
2217c478bd9Sstevel@tonic-gate } else {
2227c478bd9Sstevel@tonic-gate *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate *p = '\0';
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate /* check /etc/hosts.equiv */
2287c478bd9Sstevel@tonic-gate if (!superuser) {
2297c478bd9Sstevel@tonic-gate if ((hostf = fopen("/etc/hosts.equiv", "r")) != NULL) {
2307c478bd9Sstevel@tonic-gate if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
2317c478bd9Sstevel@tonic-gate (void) fclose(hostf);
2327c478bd9Sstevel@tonic-gate return(0);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate (void) fclose(hostf);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate /* check ~/.rhosts */
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate if ((pwd = getpwnam(luser)) == NULL)
2417c478bd9Sstevel@tonic-gate return(-1);
2427c478bd9Sstevel@tonic-gate (void)strcpy(pbuf, pwd->pw_dir);
2437c478bd9Sstevel@tonic-gate (void)strcat(pbuf, "/.rhosts");
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate /*
2467c478bd9Sstevel@tonic-gate * Read .rhosts as the local user to avoid NFS mapping the root uid
2477c478bd9Sstevel@tonic-gate * to something that can't read .rhosts.
2487c478bd9Sstevel@tonic-gate */
2497c478bd9Sstevel@tonic-gate euid = geteuid();
2507c478bd9Sstevel@tonic-gate (void) seteuid (pwd->pw_uid);
2517c478bd9Sstevel@tonic-gate if ((hostf = fopen(pbuf, "r")) == NULL) {
2527c478bd9Sstevel@tonic-gate if (euid != -1)
2537c478bd9Sstevel@tonic-gate (void) seteuid (euid);
2547c478bd9Sstevel@tonic-gate return(-1);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate (void)fstat(fileno(hostf), &sbuf);
2577c478bd9Sstevel@tonic-gate if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
2587c478bd9Sstevel@tonic-gate fclose(hostf);
2597c478bd9Sstevel@tonic-gate if (euid != -1)
2607c478bd9Sstevel@tonic-gate (void) seteuid (euid);
2617c478bd9Sstevel@tonic-gate return(-1);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
2657c478bd9Sstevel@tonic-gate (void) fclose(hostf);
2667c478bd9Sstevel@tonic-gate if (euid != -1)
2677c478bd9Sstevel@tonic-gate (void) seteuid (euid);
2687c478bd9Sstevel@tonic-gate return(0);
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate (void) fclose(hostf);
2727c478bd9Sstevel@tonic-gate if (euid != -1)
2737c478bd9Sstevel@tonic-gate (void) seteuid (euid);
2747c478bd9Sstevel@tonic-gate return (-1);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate
277*5d54f3d8Smuffin int
_validuser(FILE * hostf,char * rhost,char * luser,char * ruser,int baselen)278*5d54f3d8Smuffin _validuser(FILE *hostf, char *rhost, char *luser, char *ruser, int baselen)
2797c478bd9Sstevel@tonic-gate {
2807c478bd9Sstevel@tonic-gate char *user;
2817c478bd9Sstevel@tonic-gate char ahost[MAXHOSTNAMELEN];
2827c478bd9Sstevel@tonic-gate int hostmatch, usermatch;
283*5d54f3d8Smuffin char *p;
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate if (domain == NULL) {
2867c478bd9Sstevel@tonic-gate (void) yp_get_default_domain(&domain);
2877c478bd9Sstevel@tonic-gate }
2887c478bd9Sstevel@tonic-gate while (fgets(ahost, sizeof (ahost), hostf)) {
2897c478bd9Sstevel@tonic-gate hostmatch = usermatch = 0; /* bugid fix 1033104 */
2907c478bd9Sstevel@tonic-gate p = ahost;
2917c478bd9Sstevel@tonic-gate while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
2927c478bd9Sstevel@tonic-gate *p = isupper(*p) ? tolower(*p) : *p;
2937c478bd9Sstevel@tonic-gate p++;
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate if (*p == ' ' || *p == '\t') {
2967c478bd9Sstevel@tonic-gate *p++ = '\0';
2977c478bd9Sstevel@tonic-gate while (*p == ' ' || *p == '\t')
2987c478bd9Sstevel@tonic-gate p++;
2997c478bd9Sstevel@tonic-gate user = p;
3007c478bd9Sstevel@tonic-gate while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
3017c478bd9Sstevel@tonic-gate p++;
3027c478bd9Sstevel@tonic-gate } else
3037c478bd9Sstevel@tonic-gate user = p;
3047c478bd9Sstevel@tonic-gate *p = '\0';
3057c478bd9Sstevel@tonic-gate if (ahost[0] == '+' && ahost[1] == 0)
3067c478bd9Sstevel@tonic-gate hostmatch = 1;
3077c478bd9Sstevel@tonic-gate else if (ahost[0] == '+' && ahost[1] == '@')
3087c478bd9Sstevel@tonic-gate hostmatch = innetgr(ahost + 2, rhost,
3097c478bd9Sstevel@tonic-gate NULL, domain);
3107c478bd9Sstevel@tonic-gate else if (ahost[0] == '-' && ahost[1] == '@') {
3117c478bd9Sstevel@tonic-gate if (innetgr(ahost + 2, rhost, NULL, domain))
3127c478bd9Sstevel@tonic-gate break;
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate else if (ahost[0] == '-') {
3157c478bd9Sstevel@tonic-gate if (_checkhost(rhost, ahost+1, baselen))
3167c478bd9Sstevel@tonic-gate break;
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate else
3197c478bd9Sstevel@tonic-gate hostmatch = _checkhost(rhost, ahost, baselen);
3207c478bd9Sstevel@tonic-gate if (user[0]) {
3217c478bd9Sstevel@tonic-gate if (user[0] == '+' && user[1] == 0)
3227c478bd9Sstevel@tonic-gate usermatch = 1;
3237c478bd9Sstevel@tonic-gate else if (user[0] == '+' && user[1] == '@')
3247c478bd9Sstevel@tonic-gate usermatch = innetgr(user+2, NULL,
3257c478bd9Sstevel@tonic-gate ruser, domain);
3267c478bd9Sstevel@tonic-gate else if (user[0] == '-' && user[1] == '@') {
3277c478bd9Sstevel@tonic-gate if (hostmatch && innetgr(user+2, NULL,
3287c478bd9Sstevel@tonic-gate ruser, domain))
3297c478bd9Sstevel@tonic-gate break;
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate else if (user[0] == '-') {
3327c478bd9Sstevel@tonic-gate if (hostmatch && !strcmp(user+1, ruser))
3337c478bd9Sstevel@tonic-gate break;
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate else
3367c478bd9Sstevel@tonic-gate usermatch = !strcmp(user, ruser);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate else
3397c478bd9Sstevel@tonic-gate usermatch = !strcmp(ruser, luser);
3407c478bd9Sstevel@tonic-gate if (hostmatch && usermatch)
3417c478bd9Sstevel@tonic-gate return (0);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate return (-1);
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate
346*5d54f3d8Smuffin int
_checkhost(char * rhost,char * lhost,int len)347*5d54f3d8Smuffin _checkhost(char *rhost, char *lhost, int len)
3487c478bd9Sstevel@tonic-gate {
3497c478bd9Sstevel@tonic-gate static char *ldomain;
3507c478bd9Sstevel@tonic-gate static char *domainp;
3517c478bd9Sstevel@tonic-gate static int nodomain;
352*5d54f3d8Smuffin char *cp;
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate if (ldomain == NULL) {
3557c478bd9Sstevel@tonic-gate ldomain = (char *)malloc(MAXHOSTNAMELEN+1);
3567c478bd9Sstevel@tonic-gate if (ldomain == 0)
3577c478bd9Sstevel@tonic-gate return (0);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate if (len == -1)
3617c478bd9Sstevel@tonic-gate return(!strcmp(rhost, lhost));
3627c478bd9Sstevel@tonic-gate if (strncmp(rhost, lhost, len))
3637c478bd9Sstevel@tonic-gate return(0);
3647c478bd9Sstevel@tonic-gate if (!strcmp(rhost, lhost))
3657c478bd9Sstevel@tonic-gate return(1);
3667c478bd9Sstevel@tonic-gate if (*(lhost + len) != '\0')
3677c478bd9Sstevel@tonic-gate return(0);
3687c478bd9Sstevel@tonic-gate if (nodomain)
3697c478bd9Sstevel@tonic-gate return(0);
3707c478bd9Sstevel@tonic-gate if (!domainp) {
3717c478bd9Sstevel@tonic-gate /*
3727c478bd9Sstevel@tonic-gate * "domainp" points after the first dot in the host name
3737c478bd9Sstevel@tonic-gate */
3747c478bd9Sstevel@tonic-gate if (gethostname(ldomain, MAXHOSTNAMELEN) == -1) {
3757c478bd9Sstevel@tonic-gate nodomain = 1;
3767c478bd9Sstevel@tonic-gate return(0);
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate ldomain[MAXHOSTNAMELEN] = NULL;
3797c478bd9Sstevel@tonic-gate if ((domainp = index(ldomain, '.')) == (char *)NULL) {
3807c478bd9Sstevel@tonic-gate nodomain = 1;
3817c478bd9Sstevel@tonic-gate return(0);
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate domainp++;
3847c478bd9Sstevel@tonic-gate cp = domainp;
3857c478bd9Sstevel@tonic-gate while (*cp) {
3867c478bd9Sstevel@tonic-gate *cp = isupper(*cp) ? tolower(*cp) : *cp;
3877c478bd9Sstevel@tonic-gate cp++;
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate return(!strcmp(domainp, rhost + len +1));
3917c478bd9Sstevel@tonic-gate }
392