1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
3*0Sstevel@tonic-gate  * Use is subject to license terms.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate 
6*0Sstevel@tonic-gate /*
7*0Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
8*0Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
9*0Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
10*0Sstevel@tonic-gate  */
11*0Sstevel@tonic-gate 
12*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
13*0Sstevel@tonic-gate 
14*0Sstevel@tonic-gate #include <stdio.h>
15*0Sstevel@tonic-gate #include <ctype.h>
16*0Sstevel@tonic-gate #include <pwd.h>
17*0Sstevel@tonic-gate #include <sys/param.h>
18*0Sstevel@tonic-gate #include <sys/file.h>
19*0Sstevel@tonic-gate #include <sys/signal.h>
20*0Sstevel@tonic-gate #include <sys/socket.h>
21*0Sstevel@tonic-gate #include <sys/stat.h>
22*0Sstevel@tonic-gate 
23*0Sstevel@tonic-gate #include <netinet/in.h>
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate #include <netdb.h>
26*0Sstevel@tonic-gate #include <errno.h>
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate extern	errno;
29*0Sstevel@tonic-gate char	*index(), *strcpy();
30*0Sstevel@tonic-gate #ifndef	S5EMUL
31*0Sstevel@tonic-gate char	*sprintf();
32*0Sstevel@tonic-gate #endif
33*0Sstevel@tonic-gate static char *domain;
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate int
36*0Sstevel@tonic-gate rcmd(
37*0Sstevel@tonic-gate 	char **ahost,
38*0Sstevel@tonic-gate 	unsigned short rport,
39*0Sstevel@tonic-gate 	const char *locuser,
40*0Sstevel@tonic-gate 	const char *remuser,
41*0Sstevel@tonic-gate 	const char *cmd,
42*0Sstevel@tonic-gate 	int *fd2p)
43*0Sstevel@tonic-gate {
44*0Sstevel@tonic-gate 	int s, timo = 1, pid, oldmask, retval;
45*0Sstevel@tonic-gate 	struct sockaddr_in sin, from;
46*0Sstevel@tonic-gate 	char c;
47*0Sstevel@tonic-gate 	int lport = IPPORT_RESERVED - 1;
48*0Sstevel@tonic-gate 	struct hostent *hp;
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate 	pid = getpid();
51*0Sstevel@tonic-gate 	hp = gethostbyname(*ahost);
52*0Sstevel@tonic-gate 	if (hp == 0) {
53*0Sstevel@tonic-gate 		fprintf(stderr, "%s: unknown host\n", *ahost);
54*0Sstevel@tonic-gate 		return (-1);
55*0Sstevel@tonic-gate 	}
56*0Sstevel@tonic-gate 	*ahost = hp->h_name;
57*0Sstevel@tonic-gate 	oldmask = sigblock(sigmask(SIGURG));
58*0Sstevel@tonic-gate 	for (;;) {
59*0Sstevel@tonic-gate 		s = rresvport(&lport);
60*0Sstevel@tonic-gate 		if (s < 0) {
61*0Sstevel@tonic-gate 			if (errno == EAGAIN)
62*0Sstevel@tonic-gate 				fprintf(stderr, "socket: All ports in use\n");
63*0Sstevel@tonic-gate 			else
64*0Sstevel@tonic-gate 				perror("rcmd: socket");
65*0Sstevel@tonic-gate 			sigsetmask(oldmask);
66*0Sstevel@tonic-gate 			return (-1);
67*0Sstevel@tonic-gate 		}
68*0Sstevel@tonic-gate 		fcntl(s, F_SETOWN, pid);
69*0Sstevel@tonic-gate 		sin.sin_family = hp->h_addrtype;
70*0Sstevel@tonic-gate 		bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
71*0Sstevel@tonic-gate 		sin.sin_port = rport;
72*0Sstevel@tonic-gate 		if (connect(s, &sin, sizeof (sin)) >= 0)
73*0Sstevel@tonic-gate 			break;
74*0Sstevel@tonic-gate 		(void) close(s);
75*0Sstevel@tonic-gate 		if (errno == EADDRINUSE) {
76*0Sstevel@tonic-gate 			lport--;
77*0Sstevel@tonic-gate 			continue;
78*0Sstevel@tonic-gate 		}
79*0Sstevel@tonic-gate 		if (errno == ECONNREFUSED && timo <= 16) {
80*0Sstevel@tonic-gate 			sleep(timo);
81*0Sstevel@tonic-gate 			timo *= 2;
82*0Sstevel@tonic-gate 			continue;
83*0Sstevel@tonic-gate 		}
84*0Sstevel@tonic-gate 		if (hp->h_addr_list[1] != NULL) {
85*0Sstevel@tonic-gate 			int oerrno = errno;
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 			fprintf(stderr,
88*0Sstevel@tonic-gate 			    "connect to address %s: ", inet_ntoa(sin.sin_addr));
89*0Sstevel@tonic-gate 			errno = oerrno;
90*0Sstevel@tonic-gate 			perror(0);
91*0Sstevel@tonic-gate 			hp->h_addr_list++;
92*0Sstevel@tonic-gate 			bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
93*0Sstevel@tonic-gate 			    hp->h_length);
94*0Sstevel@tonic-gate 			fprintf(stderr, "Trying %s...\n",
95*0Sstevel@tonic-gate 				inet_ntoa(sin.sin_addr));
96*0Sstevel@tonic-gate 			continue;
97*0Sstevel@tonic-gate 		}
98*0Sstevel@tonic-gate 		perror(hp->h_name);
99*0Sstevel@tonic-gate 		sigsetmask(oldmask);
100*0Sstevel@tonic-gate 		return (-1);
101*0Sstevel@tonic-gate 	}
102*0Sstevel@tonic-gate 	lport--;
103*0Sstevel@tonic-gate 	if (fd2p == 0) {
104*0Sstevel@tonic-gate 		write(s, "", 1);
105*0Sstevel@tonic-gate 		lport = 0;
106*0Sstevel@tonic-gate 	} else {
107*0Sstevel@tonic-gate 		char num[8];
108*0Sstevel@tonic-gate 		int s2 = rresvport(&lport), s3;
109*0Sstevel@tonic-gate 		int len = sizeof (from);
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 		if (s2 < 0)
112*0Sstevel@tonic-gate 			goto bad;
113*0Sstevel@tonic-gate 		listen(s2, 1);
114*0Sstevel@tonic-gate 		(void) sprintf(num, "%d", lport);
115*0Sstevel@tonic-gate 		if (write(s, num, strlen(num)+1) != strlen(num)+1) {
116*0Sstevel@tonic-gate 			perror("write: setting up stderr");
117*0Sstevel@tonic-gate 			(void) close(s2);
118*0Sstevel@tonic-gate 			goto bad;
119*0Sstevel@tonic-gate 		}
120*0Sstevel@tonic-gate 		s3 = accept(s2, &from, &len);
121*0Sstevel@tonic-gate 		(void) close(s2);
122*0Sstevel@tonic-gate 		if (s3 < 0) {
123*0Sstevel@tonic-gate 			perror("accept");
124*0Sstevel@tonic-gate 			lport = 0;
125*0Sstevel@tonic-gate 			goto bad;
126*0Sstevel@tonic-gate 		}
127*0Sstevel@tonic-gate 		*fd2p = s3;
128*0Sstevel@tonic-gate 		from.sin_port = ntohs((u_short)from.sin_port);
129*0Sstevel@tonic-gate 		if (from.sin_family != AF_INET ||
130*0Sstevel@tonic-gate 		    from.sin_port >= IPPORT_RESERVED) {
131*0Sstevel@tonic-gate 			fprintf(stderr,
132*0Sstevel@tonic-gate 			    "socket: protocol failure in circuit setup.\n");
133*0Sstevel@tonic-gate 			goto bad2;
134*0Sstevel@tonic-gate 		}
135*0Sstevel@tonic-gate 	}
136*0Sstevel@tonic-gate 	(void) write(s, locuser, strlen(locuser)+1);
137*0Sstevel@tonic-gate 	(void) write(s, remuser, strlen(remuser)+1);
138*0Sstevel@tonic-gate 	(void) write(s, cmd, strlen(cmd)+1);
139*0Sstevel@tonic-gate 	retval = read(s, &c, 1);
140*0Sstevel@tonic-gate 	if (retval != 1) {
141*0Sstevel@tonic-gate 		if (retval == 0) {
142*0Sstevel@tonic-gate 		    fprintf(stderr,
143*0Sstevel@tonic-gate 		      "Protocol error, %s closed connection\n", *ahost);
144*0Sstevel@tonic-gate 		} else if (retval < 0) {
145*0Sstevel@tonic-gate 		    perror(*ahost);
146*0Sstevel@tonic-gate 		} else {
147*0Sstevel@tonic-gate 		    fprintf(stderr,
148*0Sstevel@tonic-gate 		      "Protocol error, %s sent %d bytes\n", *ahost, retval);
149*0Sstevel@tonic-gate 		}
150*0Sstevel@tonic-gate 		goto bad2;
151*0Sstevel@tonic-gate 	}
152*0Sstevel@tonic-gate 	if (c != 0) {
153*0Sstevel@tonic-gate 		while (read(s, &c, 1) == 1) {
154*0Sstevel@tonic-gate 			(void) write(2, &c, 1);
155*0Sstevel@tonic-gate 			if (c == '\n')
156*0Sstevel@tonic-gate 				break;
157*0Sstevel@tonic-gate 		}
158*0Sstevel@tonic-gate 		goto bad2;
159*0Sstevel@tonic-gate 	}
160*0Sstevel@tonic-gate 	sigsetmask(oldmask);
161*0Sstevel@tonic-gate 	return (s);
162*0Sstevel@tonic-gate bad2:
163*0Sstevel@tonic-gate 	if (lport)
164*0Sstevel@tonic-gate 		(void) close(*fd2p);
165*0Sstevel@tonic-gate bad:
166*0Sstevel@tonic-gate 	(void) close(s);
167*0Sstevel@tonic-gate 	sigsetmask(oldmask);
168*0Sstevel@tonic-gate 	return (-1);
169*0Sstevel@tonic-gate }
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate int
172*0Sstevel@tonic-gate rresvport(alport)
173*0Sstevel@tonic-gate 	int *alport;
174*0Sstevel@tonic-gate {
175*0Sstevel@tonic-gate 	struct sockaddr_in sin;
176*0Sstevel@tonic-gate 	int s;
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	sin.sin_family = AF_INET;
179*0Sstevel@tonic-gate 	sin.sin_addr.s_addr = INADDR_ANY;
180*0Sstevel@tonic-gate 	s = socket(AF_INET, SOCK_STREAM, 0);
181*0Sstevel@tonic-gate 	if (s < 0)
182*0Sstevel@tonic-gate 		return (-1);
183*0Sstevel@tonic-gate 	for (;;) {
184*0Sstevel@tonic-gate 		sin.sin_port = htons((u_short)*alport);
185*0Sstevel@tonic-gate 		if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
186*0Sstevel@tonic-gate 			return (s);
187*0Sstevel@tonic-gate 		if (errno != EADDRINUSE) {
188*0Sstevel@tonic-gate 			(void) close(s);
189*0Sstevel@tonic-gate 			return (-1);
190*0Sstevel@tonic-gate 		}
191*0Sstevel@tonic-gate 		(*alport)--;
192*0Sstevel@tonic-gate 		if (*alport == IPPORT_RESERVED/2) {
193*0Sstevel@tonic-gate 			(void) close(s);
194*0Sstevel@tonic-gate 			errno = EAGAIN;		/* close */
195*0Sstevel@tonic-gate 			return (-1);
196*0Sstevel@tonic-gate 		}
197*0Sstevel@tonic-gate 	}
198*0Sstevel@tonic-gate }
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate int
201*0Sstevel@tonic-gate ruserok(
202*0Sstevel@tonic-gate 	const char *rhost,
203*0Sstevel@tonic-gate 	int superuser,
204*0Sstevel@tonic-gate 	const char *ruser,
205*0Sstevel@tonic-gate 	const char *luser)
206*0Sstevel@tonic-gate {
207*0Sstevel@tonic-gate 	FILE *hostf;
208*0Sstevel@tonic-gate 	char fhost[MAXHOSTNAMELEN];
209*0Sstevel@tonic-gate 	register const char *sp;
210*0Sstevel@tonic-gate 	register char *p;
211*0Sstevel@tonic-gate 	int baselen = -1;
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 	struct stat sbuf;
214*0Sstevel@tonic-gate 	struct passwd *pwd;
215*0Sstevel@tonic-gate 	char pbuf[MAXPATHLEN];
216*0Sstevel@tonic-gate 	int euid = -1;
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 	sp = rhost;
219*0Sstevel@tonic-gate 	p = fhost;
220*0Sstevel@tonic-gate 	while (*sp) {
221*0Sstevel@tonic-gate 		if (*sp == '.') {
222*0Sstevel@tonic-gate 			if (baselen == -1)
223*0Sstevel@tonic-gate 				baselen = sp - rhost;
224*0Sstevel@tonic-gate 			*p++ = *sp++;
225*0Sstevel@tonic-gate 		} else {
226*0Sstevel@tonic-gate 			*p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
227*0Sstevel@tonic-gate 		}
228*0Sstevel@tonic-gate 	}
229*0Sstevel@tonic-gate 	*p = '\0';
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	/* check /etc/hosts.equiv */
232*0Sstevel@tonic-gate 	if (!superuser) {
233*0Sstevel@tonic-gate 		if ((hostf = fopen("/etc/hosts.equiv", "r")) != NULL) {
234*0Sstevel@tonic-gate 			if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
235*0Sstevel@tonic-gate 				(void) fclose(hostf);
236*0Sstevel@tonic-gate 				return(0);
237*0Sstevel@tonic-gate 		        }
238*0Sstevel@tonic-gate 			(void) fclose(hostf);
239*0Sstevel@tonic-gate 		}
240*0Sstevel@tonic-gate 	}
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	/* check ~/.rhosts */
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 	if ((pwd = getpwnam(luser)) == NULL)
245*0Sstevel@tonic-gate        		return(-1);
246*0Sstevel@tonic-gate 	(void)strcpy(pbuf, pwd->pw_dir);
247*0Sstevel@tonic-gate 	(void)strcat(pbuf, "/.rhosts");
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 	/*
250*0Sstevel@tonic-gate 	 * Read .rhosts as the local user to avoid NFS mapping the root uid
251*0Sstevel@tonic-gate 	 * to something that can't read .rhosts.
252*0Sstevel@tonic-gate 	 */
253*0Sstevel@tonic-gate 	euid = geteuid();
254*0Sstevel@tonic-gate 	(void) seteuid (pwd->pw_uid);
255*0Sstevel@tonic-gate 	if ((hostf = fopen(pbuf, "r")) == NULL) {
256*0Sstevel@tonic-gate 		if (euid != -1)
257*0Sstevel@tonic-gate 	    		(void) seteuid (euid);
258*0Sstevel@tonic-gate 	  	return(-1);
259*0Sstevel@tonic-gate 	}
260*0Sstevel@tonic-gate 	(void)fstat(fileno(hostf), &sbuf);
261*0Sstevel@tonic-gate 	if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
262*0Sstevel@tonic-gate 	  	fclose(hostf);
263*0Sstevel@tonic-gate 		if (euid != -1)
264*0Sstevel@tonic-gate 		  	(void) seteuid (euid);
265*0Sstevel@tonic-gate 		return(-1);
266*0Sstevel@tonic-gate 	}
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate 	if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
269*0Sstevel@tonic-gate 	  	(void) fclose(hostf);
270*0Sstevel@tonic-gate 		if (euid != -1)
271*0Sstevel@tonic-gate 			(void) seteuid (euid);
272*0Sstevel@tonic-gate 		return(0);
273*0Sstevel@tonic-gate 	}
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate 	(void) fclose(hostf);
276*0Sstevel@tonic-gate 	if (euid != -1)
277*0Sstevel@tonic-gate        		(void) seteuid (euid);
278*0Sstevel@tonic-gate 	return (-1);
279*0Sstevel@tonic-gate }
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate _validuser(hostf, rhost, luser, ruser, baselen)
282*0Sstevel@tonic-gate char *rhost, *luser, *ruser;
283*0Sstevel@tonic-gate FILE *hostf;
284*0Sstevel@tonic-gate int baselen;
285*0Sstevel@tonic-gate {
286*0Sstevel@tonic-gate 	char *user;
287*0Sstevel@tonic-gate 	char ahost[MAXHOSTNAMELEN];
288*0Sstevel@tonic-gate 	int hostmatch, usermatch;
289*0Sstevel@tonic-gate 	register char *p;
290*0Sstevel@tonic-gate 
291*0Sstevel@tonic-gate 	if (domain == NULL) {
292*0Sstevel@tonic-gate                 (void) yp_get_default_domain(&domain);
293*0Sstevel@tonic-gate         }
294*0Sstevel@tonic-gate 	while (fgets(ahost, sizeof (ahost), hostf)) {
295*0Sstevel@tonic-gate 		hostmatch = usermatch = 0;	/* bugid fix 1033104 */
296*0Sstevel@tonic-gate 		p = ahost;
297*0Sstevel@tonic-gate 		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
298*0Sstevel@tonic-gate 			*p = isupper(*p) ? tolower(*p) : *p;
299*0Sstevel@tonic-gate 			p++;
300*0Sstevel@tonic-gate 		}
301*0Sstevel@tonic-gate 		if (*p == ' ' || *p == '\t') {
302*0Sstevel@tonic-gate 			*p++ = '\0';
303*0Sstevel@tonic-gate 			while (*p == ' ' || *p == '\t')
304*0Sstevel@tonic-gate 				p++;
305*0Sstevel@tonic-gate 			user = p;
306*0Sstevel@tonic-gate 			while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
307*0Sstevel@tonic-gate 				p++;
308*0Sstevel@tonic-gate 		} else
309*0Sstevel@tonic-gate 			user = p;
310*0Sstevel@tonic-gate 		*p = '\0';
311*0Sstevel@tonic-gate 		if (ahost[0] == '+' && ahost[1] == 0)
312*0Sstevel@tonic-gate 			hostmatch = 1;
313*0Sstevel@tonic-gate 		else if (ahost[0] == '+' && ahost[1] == '@')
314*0Sstevel@tonic-gate 			hostmatch = innetgr(ahost + 2, rhost,
315*0Sstevel@tonic-gate 			    NULL, domain);
316*0Sstevel@tonic-gate 		else if (ahost[0] == '-' && ahost[1] == '@') {
317*0Sstevel@tonic-gate 			if (innetgr(ahost + 2, rhost, NULL, domain))
318*0Sstevel@tonic-gate 				break;
319*0Sstevel@tonic-gate 		}
320*0Sstevel@tonic-gate 		else if (ahost[0] == '-') {
321*0Sstevel@tonic-gate 			if (_checkhost(rhost, ahost+1, baselen))
322*0Sstevel@tonic-gate 				break;
323*0Sstevel@tonic-gate 		}
324*0Sstevel@tonic-gate 		else
325*0Sstevel@tonic-gate 			hostmatch = _checkhost(rhost, ahost, baselen);
326*0Sstevel@tonic-gate 		if (user[0]) {
327*0Sstevel@tonic-gate 			if (user[0] == '+' && user[1] == 0)
328*0Sstevel@tonic-gate 				usermatch = 1;
329*0Sstevel@tonic-gate 			else if (user[0] == '+' && user[1] == '@')
330*0Sstevel@tonic-gate 				usermatch = innetgr(user+2, NULL,
331*0Sstevel@tonic-gate 				    ruser, domain);
332*0Sstevel@tonic-gate 			else if (user[0] == '-' && user[1] == '@') {
333*0Sstevel@tonic-gate 				if (hostmatch && innetgr(user+2, NULL,
334*0Sstevel@tonic-gate 				    ruser, domain))
335*0Sstevel@tonic-gate 					break;
336*0Sstevel@tonic-gate 			}
337*0Sstevel@tonic-gate 			else if (user[0] == '-') {
338*0Sstevel@tonic-gate 				if (hostmatch && !strcmp(user+1, ruser))
339*0Sstevel@tonic-gate 					break;
340*0Sstevel@tonic-gate 			}
341*0Sstevel@tonic-gate 			else
342*0Sstevel@tonic-gate 				usermatch = !strcmp(user, ruser);
343*0Sstevel@tonic-gate 		}
344*0Sstevel@tonic-gate 		else
345*0Sstevel@tonic-gate 			usermatch = !strcmp(ruser, luser);
346*0Sstevel@tonic-gate 		if (hostmatch && usermatch)
347*0Sstevel@tonic-gate 			return (0);
348*0Sstevel@tonic-gate 	}
349*0Sstevel@tonic-gate 	return (-1);
350*0Sstevel@tonic-gate }
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate _checkhost(rhost, lhost, len)
353*0Sstevel@tonic-gate char *rhost, *lhost;
354*0Sstevel@tonic-gate int len;
355*0Sstevel@tonic-gate {
356*0Sstevel@tonic-gate 	static char *ldomain;
357*0Sstevel@tonic-gate 	static char *domainp;
358*0Sstevel@tonic-gate 	static int nodomain;
359*0Sstevel@tonic-gate 	register char *cp;
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 	if (ldomain == NULL) {
362*0Sstevel@tonic-gate 		ldomain = (char *)malloc(MAXHOSTNAMELEN+1);
363*0Sstevel@tonic-gate 		if (ldomain == 0)
364*0Sstevel@tonic-gate 			return (0);
365*0Sstevel@tonic-gate 	}
366*0Sstevel@tonic-gate 
367*0Sstevel@tonic-gate 	if (len == -1)
368*0Sstevel@tonic-gate 		return(!strcmp(rhost, lhost));
369*0Sstevel@tonic-gate 	if (strncmp(rhost, lhost, len))
370*0Sstevel@tonic-gate 		return(0);
371*0Sstevel@tonic-gate 	if (!strcmp(rhost, lhost))
372*0Sstevel@tonic-gate 		return(1);
373*0Sstevel@tonic-gate 	if (*(lhost + len) != '\0')
374*0Sstevel@tonic-gate 		return(0);
375*0Sstevel@tonic-gate 	if (nodomain)
376*0Sstevel@tonic-gate 		return(0);
377*0Sstevel@tonic-gate 	if (!domainp) {
378*0Sstevel@tonic-gate 		/*
379*0Sstevel@tonic-gate 		 * "domainp" points after the first dot in the host name
380*0Sstevel@tonic-gate 		 */
381*0Sstevel@tonic-gate 		if (gethostname(ldomain, MAXHOSTNAMELEN) == -1) {
382*0Sstevel@tonic-gate 			nodomain = 1;
383*0Sstevel@tonic-gate 			return(0);
384*0Sstevel@tonic-gate 		}
385*0Sstevel@tonic-gate 		ldomain[MAXHOSTNAMELEN] = NULL;
386*0Sstevel@tonic-gate 		if ((domainp = index(ldomain, '.')) == (char *)NULL) {
387*0Sstevel@tonic-gate 			nodomain = 1;
388*0Sstevel@tonic-gate 			return(0);
389*0Sstevel@tonic-gate 		}
390*0Sstevel@tonic-gate 		domainp++;
391*0Sstevel@tonic-gate 		cp = domainp;
392*0Sstevel@tonic-gate 		while (*cp) {
393*0Sstevel@tonic-gate 			*cp = isupper(*cp) ? tolower(*cp) : *cp;
394*0Sstevel@tonic-gate 			cp++;
395*0Sstevel@tonic-gate 		}
396*0Sstevel@tonic-gate 	}
397*0Sstevel@tonic-gate 	return(!strcmp(domainp, rhost + len +1));
398*0Sstevel@tonic-gate }
399