xref: /titanic_51/usr/src/lib/libast/common/uwin/rcmd.c (revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968)
1*da2e3ebdSchin #include "FEATURE/uwin"
2*da2e3ebdSchin 
3*da2e3ebdSchin #if !_UWIN || _lib_rcmd
4*da2e3ebdSchin 
_STUB_rcmd()5*da2e3ebdSchin void _STUB_rcmd(){}
6*da2e3ebdSchin 
7*da2e3ebdSchin #else
8*da2e3ebdSchin 
9*da2e3ebdSchin /*
10*da2e3ebdSchin  * Copyright (c) 1983
11*da2e3ebdSchin  *	The Regents of the University of California.  All rights reserved.
12*da2e3ebdSchin  *
13*da2e3ebdSchin  * Redistribution and use in source and binary forms, with or without
14*da2e3ebdSchin  * modification, are permitted provided that the following conditions
15*da2e3ebdSchin  * are met:
16*da2e3ebdSchin  * 1. Redistributions of source code must retain the above copyright
17*da2e3ebdSchin  *    notice, this list of conditions and the following disclaimer.
18*da2e3ebdSchin  * 2. Redistributions in binary form must reproduce the above copyright
19*da2e3ebdSchin  *    notice, this list of conditions and the following disclaimer in the
20*da2e3ebdSchin  *    documentation and/or other materials provided with the distribution.
21*da2e3ebdSchin  * 3. Neither the name of the University nor the names of its contributors
22*da2e3ebdSchin  *    may be used to endorse or promote products derived from this software
23*da2e3ebdSchin  *    without specific prior written permission.
24*da2e3ebdSchin  *
25*da2e3ebdSchin  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26*da2e3ebdSchin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27*da2e3ebdSchin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28*da2e3ebdSchin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29*da2e3ebdSchin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30*da2e3ebdSchin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31*da2e3ebdSchin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32*da2e3ebdSchin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33*da2e3ebdSchin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34*da2e3ebdSchin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35*da2e3ebdSchin  * SUCH DAMAGE.
36*da2e3ebdSchin  */
37*da2e3ebdSchin 
38*da2e3ebdSchin #if defined(LIBC_SCCS) && !defined(lint)
39*da2e3ebdSchin static char sccsid[] = "@(#)rcmd.c	5.17 (Berkeley) 6/27/88";
40*da2e3ebdSchin #endif /* LIBC_SCCS and not lint */
41*da2e3ebdSchin 
42*da2e3ebdSchin #include "rlib.h"
43*da2e3ebdSchin #include <pwd.h>
44*da2e3ebdSchin #include <sys/file.h>
45*da2e3ebdSchin #include <sys/signal.h>
46*da2e3ebdSchin #if 1
47*da2e3ebdSchin #define _PATH_HEQUIV	"/etc/hosts.equiv"
48*da2e3ebdSchin #endif
49*da2e3ebdSchin #include <sys/stat.h>
50*da2e3ebdSchin 
51*da2e3ebdSchin #if NLS
52*da2e3ebdSchin #include "nl_types.h"
53*da2e3ebdSchin #endif
54*da2e3ebdSchin 
55*da2e3ebdSchin #ifdef YP
56*da2e3ebdSchin #include <rpcsvc/ypclnt.h>
57*da2e3ebdSchin extern void setnetgrent(const char *);
58*da2e3ebdSchin extern void endnetgrent(void);
59*da2e3ebdSchin extern int getnetgrent(char **, char **, char **);
60*da2e3ebdSchin static char *nisdomain = NULL;
61*da2e3ebdSchin static int _checknetgrouphost(const char *, const char *, int);
62*da2e3ebdSchin static int _checknetgroupuser(const char *, const char *);
63*da2e3ebdSchin #endif
64*da2e3ebdSchin 
65*da2e3ebdSchin #if defined(__EXPORT__)
66*da2e3ebdSchin #define extern		__EXPORT__
67*da2e3ebdSchin #endif
68*da2e3ebdSchin 
rresvport(int * alport)69*da2e3ebdSchin extern int rresvport(int *alport)
70*da2e3ebdSchin {
71*da2e3ebdSchin 	struct sockaddr_in sin;
72*da2e3ebdSchin 	int s;
73*da2e3ebdSchin 
74*da2e3ebdSchin 	sin.sin_family = AF_INET;
75*da2e3ebdSchin 	sin.sin_addr.s_addr = INADDR_ANY;
76*da2e3ebdSchin 	s = socket(AF_INET, SOCK_STREAM, 0);
77*da2e3ebdSchin 	if (s < 0)
78*da2e3ebdSchin 		return (-1);
79*da2e3ebdSchin 	for (;;) {
80*da2e3ebdSchin 		sin.sin_port = htons((u_short)*alport);
81*da2e3ebdSchin 		if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
82*da2e3ebdSchin 			return (s);
83*da2e3ebdSchin 		if (errno != EADDRINUSE) {
84*da2e3ebdSchin 			(void) close(s);
85*da2e3ebdSchin 			return (-1);
86*da2e3ebdSchin 		}
87*da2e3ebdSchin 		(*alport)--;
88*da2e3ebdSchin 		if (*alport == IPPORT_RESERVED/2) {
89*da2e3ebdSchin 			(void) close(s);
90*da2e3ebdSchin 			errno = EAGAIN;		/* close */
91*da2e3ebdSchin 			return (-1);
92*da2e3ebdSchin 		}
93*da2e3ebdSchin 	}
94*da2e3ebdSchin }
95*da2e3ebdSchin 
rcmd(char ** ahost,unsigned short rport,const char * locuser,const char * remuser,const char * cmd,int * fd2p)96*da2e3ebdSchin extern int rcmd(char **ahost, unsigned short rport, const char *locuser, const char *remuser, const char *cmd, int *fd2p)
97*da2e3ebdSchin {
98*da2e3ebdSchin 	int s, timo = 1;
99*da2e3ebdSchin #ifdef F_SETOWN
100*da2e3ebdSchin 	pid_t pid;
101*da2e3ebdSchin #endif
102*da2e3ebdSchin #ifdef _POSIX_SOURCE
103*da2e3ebdSchin 	sigset_t set, oset;
104*da2e3ebdSchin #else
105*da2e3ebdSchin 	long oldmask;
106*da2e3ebdSchin #endif
107*da2e3ebdSchin 	struct sockaddr_in sin, from;
108*da2e3ebdSchin 	char c;
109*da2e3ebdSchin 	int lport = IPPORT_RESERVED - 1;
110*da2e3ebdSchin 	struct hostent *hp;
111*da2e3ebdSchin 
112*da2e3ebdSchin #if NLS
113*da2e3ebdSchin 	libc_nls_init();
114*da2e3ebdSchin #endif
115*da2e3ebdSchin 
116*da2e3ebdSchin #ifdef F_SETOWN
117*da2e3ebdSchin 	pid = getpid();
118*da2e3ebdSchin #endif
119*da2e3ebdSchin 	hp = gethostbyname(*ahost);
120*da2e3ebdSchin 	if (hp == 0) {
121*da2e3ebdSchin #if NLS
122*da2e3ebdSchin 		fprintf(stderr, "%s: %s\n", *ahost,
123*da2e3ebdSchin 		    catgets(_libc_cat, HerrorListSet,
124*da2e3ebdSchin 		    2, "unknown host"));
125*da2e3ebdSchin #else
126*da2e3ebdSchin 		fprintf(stderr, "%s: unknown host\n", *ahost);
127*da2e3ebdSchin #endif
128*da2e3ebdSchin 		return (-1);
129*da2e3ebdSchin 	}
130*da2e3ebdSchin 	*ahost = hp->h_name;
131*da2e3ebdSchin #ifdef SIGURG
132*da2e3ebdSchin #ifdef _POSIX_SOURCE
133*da2e3ebdSchin 	sigemptyset (&set);
134*da2e3ebdSchin 	sigaddset (&set, SIGURG);
135*da2e3ebdSchin 	sigprocmask (SIG_BLOCK, &set, &oset);
136*da2e3ebdSchin #else
137*da2e3ebdSchin 	oldmask = sigblock(sigmask(SIGURG));
138*da2e3ebdSchin #endif
139*da2e3ebdSchin #endif
140*da2e3ebdSchin 	for (;;) {
141*da2e3ebdSchin 		s = rresvport(&lport);
142*da2e3ebdSchin 		if (s < 0) {
143*da2e3ebdSchin 			if (errno == EAGAIN)
144*da2e3ebdSchin #if NLS
145*da2e3ebdSchin 				fprintf(stderr, "socket: %s\n",
146*da2e3ebdSchin 				    catgets(_libc_cat, NetMiscSet,
147*da2e3ebdSchin 				    NetMiscAllPortsInUse,
148*da2e3ebdSchin 				    "All ports in use"));
149*da2e3ebdSchin #else
150*da2e3ebdSchin 			fprintf(stderr, "socket: All ports in use\n");
151*da2e3ebdSchin #endif
152*da2e3ebdSchin 			else
153*da2e3ebdSchin #if NLS
154*da2e3ebdSchin 	perror(catgets(_libc_cat, NetMiscSet,
155*da2e3ebdSchin 	    NetMiscRcmdSocket,
156*da2e3ebdSchin 	    "rcmd: socket"));
157*da2e3ebdSchin #else
158*da2e3ebdSchin perror("rcmd: socket");
159*da2e3ebdSchin #endif
160*da2e3ebdSchin #ifdef SIGURG
161*da2e3ebdSchin #ifdef _POSIX_SOURCE
162*da2e3ebdSchin sigprocmask (SIG_SETMASK, &oset,
163*da2e3ebdSchin (sigset_t *)NULL);
164*da2e3ebdSchin #else
165*da2e3ebdSchin sigsetmask(oldmask);
166*da2e3ebdSchin #endif
167*da2e3ebdSchin #endif
168*da2e3ebdSchin return (-1);
169*da2e3ebdSchin 		}
170*da2e3ebdSchin #ifdef F_SETOWN
171*da2e3ebdSchin 		fcntl(s, F_SETOWN, pid);
172*da2e3ebdSchin #endif
173*da2e3ebdSchin 		sin.sin_family = hp->h_addrtype;
174*da2e3ebdSchin 		bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
175*da2e3ebdSchin 		sin.sin_port = rport;
176*da2e3ebdSchin 		if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
177*da2e3ebdSchin 			break;
178*da2e3ebdSchin 		(void) close(s);
179*da2e3ebdSchin 		if (errno == EADDRINUSE) {
180*da2e3ebdSchin 			lport--;
181*da2e3ebdSchin 			continue;
182*da2e3ebdSchin 		}
183*da2e3ebdSchin 		if (errno == ECONNREFUSED && timo <= 16) {
184*da2e3ebdSchin 			sleep(timo);
185*da2e3ebdSchin 			timo *= 2;
186*da2e3ebdSchin 			continue;
187*da2e3ebdSchin 		}
188*da2e3ebdSchin 		if (hp->h_addr_list[1] != NULL) {
189*da2e3ebdSchin 			int oerrno = errno;
190*da2e3ebdSchin 
191*da2e3ebdSchin 			fprintf(stderr,
192*da2e3ebdSchin #if NLS
193*da2e3ebdSchin 			    "%s %s: ", catgets(_libc_cat, NetMiscSet,
194*da2e3ebdSchin 			    NetMiscAllPortsInUse,
195*da2e3ebdSchin 			    "connect to address"),
196*da2e3ebdSchin 			    inet_ntoa(sin.sin_addr));
197*da2e3ebdSchin 
198*da2e3ebdSchin #else
199*da2e3ebdSchin 
200*da2e3ebdSchin 			"connect to address %s: ", inet_ntoa(sin.sin_addr));
201*da2e3ebdSchin #endif
202*da2e3ebdSchin 			errno = oerrno;
203*da2e3ebdSchin 			perror(0);
204*da2e3ebdSchin 			hp->h_addr_list++;
205*da2e3ebdSchin 			bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
206*da2e3ebdSchin 			    hp->h_length);
207*da2e3ebdSchin 
208*da2e3ebdSchin #if NLS
209*da2e3ebdSchin 			fprintf(stderr, catgets(_libc_cat, NetMiscSet,
210*da2e3ebdSchin 			    NetMiscTrying,
211*da2e3ebdSchin 			    "Trying %s...\n"),
212*da2e3ebdSchin #else
213*da2e3ebdSchin 			    fprintf(stderr,	"Trying %s...\n",
214*da2e3ebdSchin #endif
215*da2e3ebdSchin 			    inet_ntoa(sin.sin_addr));
216*da2e3ebdSchin 			    continue;
217*da2e3ebdSchin 		}
218*da2e3ebdSchin 		perror(hp->h_name);
219*da2e3ebdSchin #ifdef SIGURG
220*da2e3ebdSchin #ifdef _POSIX_SOURCE
221*da2e3ebdSchin 		    sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
222*da2e3ebdSchin #else
223*da2e3ebdSchin 		    sigsetmask(oldmask);
224*da2e3ebdSchin #endif
225*da2e3ebdSchin #endif
226*da2e3ebdSchin 		    return (-1);
227*da2e3ebdSchin 	}
228*da2e3ebdSchin 	lport--;
229*da2e3ebdSchin 	    if (fd2p == 0) {
230*da2e3ebdSchin 		write(s, "", 1);
231*da2e3ebdSchin 		    lport = 0;
232*da2e3ebdSchin 	} else {
233*da2e3ebdSchin 		char num[8];
234*da2e3ebdSchin 		    int s2 = rresvport(&lport), s3;
235*da2e3ebdSchin 		    int len = sizeof (from);
236*da2e3ebdSchin 
237*da2e3ebdSchin 		    if (s2 < 0)
238*da2e3ebdSchin 		    goto bad;
239*da2e3ebdSchin 		    listen(s2, 1);
240*da2e3ebdSchin 		    (void) snprintf(num, sizeof(num), "%d", lport);
241*da2e3ebdSchin 		    if (write(s, num, strlen(num)+1) != strlen(num)+1) {
242*da2e3ebdSchin #if NLS
243*da2e3ebdSchin 			perror(catgets(_libc_cat, NetMiscSet,
244*da2e3ebdSchin 			    NetMiscSettingUpStderr,
245*da2e3ebdSchin 			    "write: setting up stderr"));
246*da2e3ebdSchin #else
247*da2e3ebdSchin 			    perror("write: setting up stderr");
248*da2e3ebdSchin #endif
249*da2e3ebdSchin 			    (void) close(s2);
250*da2e3ebdSchin 			    goto bad;
251*da2e3ebdSchin 		}
252*da2e3ebdSchin 		s3 = accept(s2, (struct sockaddr *)&from, &len);
253*da2e3ebdSchin 		    (void) close(s2);
254*da2e3ebdSchin 		    if (s3 < 0) {
255*da2e3ebdSchin #if NLS
256*da2e3ebdSchin 			perror(catgets(_libc_cat, NetMiscSet,
257*da2e3ebdSchin 			    NetMiscAccept,
258*da2e3ebdSchin 			    "accept"));
259*da2e3ebdSchin #else
260*da2e3ebdSchin 			    perror("accept");
261*da2e3ebdSchin #endif
262*da2e3ebdSchin 			    lport = 0;
263*da2e3ebdSchin 			    goto bad;
264*da2e3ebdSchin 		}
265*da2e3ebdSchin 		*fd2p = s3;
266*da2e3ebdSchin 		    from.sin_port = ntohs((u_short)from.sin_port);
267*da2e3ebdSchin 		    if (from.sin_family != AF_INET ||
268*da2e3ebdSchin 		    from.sin_port >= IPPORT_RESERVED) {
269*da2e3ebdSchin 			fprintf(stderr,
270*da2e3ebdSchin #if NLS
271*da2e3ebdSchin 			    "%s\n",
272*da2e3ebdSchin 			    catgets(_libc_cat, NetMiscSet,
273*da2e3ebdSchin 			    NetMiscProtocolFailure,
274*da2e3ebdSchin 			    "socket: protocol failure in circuit setup."));
275*da2e3ebdSchin #else
276*da2e3ebdSchin 			    "socket: protocol failure in circuit setup.\n");
277*da2e3ebdSchin #endif
278*da2e3ebdSchin 			goto bad2;
279*da2e3ebdSchin 		}
280*da2e3ebdSchin 	}
281*da2e3ebdSchin 	(void) write(s, locuser, strlen(locuser)+1);
282*da2e3ebdSchin 	(void) write(s, remuser, strlen(remuser)+1);
283*da2e3ebdSchin 	(void) write(s, cmd, strlen(cmd)+1);
284*da2e3ebdSchin 	if (read(s, &c, 1) != 1) {
285*da2e3ebdSchin 		perror(*ahost);
286*da2e3ebdSchin 		goto bad2;
287*da2e3ebdSchin 	}
288*da2e3ebdSchin 	if (c != 0) {
289*da2e3ebdSchin 		while (read(s, &c, 1) == 1) {
290*da2e3ebdSchin 			(void) write(2, &c, 1);
291*da2e3ebdSchin 			if (c == '\n')
292*da2e3ebdSchin 				break;
293*da2e3ebdSchin 		}
294*da2e3ebdSchin 		goto bad2;
295*da2e3ebdSchin 	}
296*da2e3ebdSchin #ifdef SIGURG
297*da2e3ebdSchin #ifdef _POSIX_SOURCE
298*da2e3ebdSchin 	sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
299*da2e3ebdSchin #else
300*da2e3ebdSchin 	sigsetmask(oldmask);
301*da2e3ebdSchin #endif
302*da2e3ebdSchin #endif
303*da2e3ebdSchin 	return (s);
304*da2e3ebdSchin bad2:
305*da2e3ebdSchin 	if (lport)
306*da2e3ebdSchin 		(void) close(*fd2p);
307*da2e3ebdSchin bad:
308*da2e3ebdSchin 	(void) close(s);
309*da2e3ebdSchin #ifdef SIGURG
310*da2e3ebdSchin #ifdef _POSIX_SOURCE
311*da2e3ebdSchin 	sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
312*da2e3ebdSchin #else
313*da2e3ebdSchin 	sigsetmask(oldmask);
314*da2e3ebdSchin #endif
315*da2e3ebdSchin #endif
316*da2e3ebdSchin 	return (-1);
317*da2e3ebdSchin }
318*da2e3ebdSchin 
ruserok(const char * rhost,int superuser,const char * ruser,const char * luser)319*da2e3ebdSchin extern int ruserok(const char *rhost, int superuser, const char *ruser, const char *luser)
320*da2e3ebdSchin {
321*da2e3ebdSchin 	FILE *hostf;
322*da2e3ebdSchin 	char fhost[MAXHOSTNAMELEN];
323*da2e3ebdSchin 	int first = 1;
324*da2e3ebdSchin 	register const char *sp;
325*da2e3ebdSchin 	register char *p;
326*da2e3ebdSchin 	int baselen = -1;
327*da2e3ebdSchin 	uid_t saveuid;
328*da2e3ebdSchin 
329*da2e3ebdSchin 	saveuid = geteuid();
330*da2e3ebdSchin 	sp = rhost;
331*da2e3ebdSchin 	p = fhost;
332*da2e3ebdSchin 	while (*sp) {
333*da2e3ebdSchin 		if (*sp == '.') {
334*da2e3ebdSchin 			if (baselen == -1)
335*da2e3ebdSchin 				baselen = sp - rhost;
336*da2e3ebdSchin 			*p++ = *sp++;
337*da2e3ebdSchin 		} else {
338*da2e3ebdSchin 			*p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
339*da2e3ebdSchin 		}
340*da2e3ebdSchin 	}
341*da2e3ebdSchin 	*p = '\0';
342*da2e3ebdSchin 	hostf = superuser ? (FILE *)0 : fopen(_PATH_HEQUIV, "r");
343*da2e3ebdSchin again:
344*da2e3ebdSchin 	if (hostf) {
345*da2e3ebdSchin 		if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
346*da2e3ebdSchin 			(void) fclose(hostf);
347*da2e3ebdSchin 			seteuid(saveuid);
348*da2e3ebdSchin 			return(0);
349*da2e3ebdSchin 		}
350*da2e3ebdSchin 		(void) fclose(hostf);
351*da2e3ebdSchin 	}
352*da2e3ebdSchin 	if (first == 1) {
353*da2e3ebdSchin 		struct stat sbuf;
354*da2e3ebdSchin 		struct passwd *pwd;
355*da2e3ebdSchin 		char pbuf[MAXPATHLEN];
356*da2e3ebdSchin 
357*da2e3ebdSchin 		first = 0;
358*da2e3ebdSchin 		if ((pwd = getpwnam(luser)) == NULL)
359*da2e3ebdSchin 			return(-1);
360*da2e3ebdSchin 		(void)strcpy(pbuf, pwd->pw_dir);
361*da2e3ebdSchin 		(void)strcat(pbuf, "/.rhosts");
362*da2e3ebdSchin 		(void)seteuid(pwd->pw_uid);
363*da2e3ebdSchin 		if ((hostf = fopen(pbuf, "r")) == NULL) {
364*da2e3ebdSchin 			seteuid(saveuid);
365*da2e3ebdSchin 			return(-1);
366*da2e3ebdSchin 		}
367*da2e3ebdSchin 		(void)fstat(fileno(hostf), &sbuf);
368*da2e3ebdSchin 		if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
369*da2e3ebdSchin 			fclose(hostf);
370*da2e3ebdSchin 			seteuid(saveuid);
371*da2e3ebdSchin 			return(-1);
372*da2e3ebdSchin 		}
373*da2e3ebdSchin 		goto again;
374*da2e3ebdSchin 	}
375*da2e3ebdSchin 	seteuid(saveuid);
376*da2e3ebdSchin 	return (-1);
377*da2e3ebdSchin }
378*da2e3ebdSchin 
379*da2e3ebdSchin int
_validuser(FILE * hostf,const char * rhost,const char * luser,const char * ruser,int baselen)380*da2e3ebdSchin _validuser(FILE *hostf, const char *rhost, const char *luser,
381*da2e3ebdSchin const char *ruser, int baselen)
382*da2e3ebdSchin {
383*da2e3ebdSchin 	char *user;
384*da2e3ebdSchin 	char ahost[MAXHOSTNAMELEN];
385*da2e3ebdSchin 	register char *p;
386*da2e3ebdSchin 	int hostvalid = 0;
387*da2e3ebdSchin 	int uservalid = 0;
388*da2e3ebdSchin 
389*da2e3ebdSchin 	while (fgets(ahost, sizeof (ahost), hostf)) {
390*da2e3ebdSchin 		/* We need to get rid of all comments. */
391*da2e3ebdSchin 		p = strchr (ahost, '#');
392*da2e3ebdSchin 		if (p) *p = '\0';
393*da2e3ebdSchin 		p = ahost;
394*da2e3ebdSchin 		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
395*da2e3ebdSchin 			*p = isupper(*p) ? tolower(*p) : *p;
396*da2e3ebdSchin 			p++;
397*da2e3ebdSchin 		}
398*da2e3ebdSchin 		if (*p == ' ' || *p == '\t') {
399*da2e3ebdSchin 			*p++ = '\0';
400*da2e3ebdSchin 			while (*p == ' ' || *p == '\t')
401*da2e3ebdSchin 				p++;
402*da2e3ebdSchin 			user = p;
403*da2e3ebdSchin 			while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
404*da2e3ebdSchin 				p++;
405*da2e3ebdSchin 		} else
406*da2e3ebdSchin 			user = p;
407*da2e3ebdSchin 		*p = '\0';
408*da2e3ebdSchin 	/* Adding new authentication -Nilendu */
409*da2e3ebdSchin 
410*da2e3ebdSchin 		/* enable all host for + entry */
411*da2e3ebdSchin 		if ('+' == ahost[0] && '\0' == ahost[1] )
412*da2e3ebdSchin 			hostvalid = 1;
413*da2e3ebdSchin 
414*da2e3ebdSchin 		/* enable all user for + entry */
415*da2e3ebdSchin 		if ('+' == user[0] && '\0' == user[1] )
416*da2e3ebdSchin 			uservalid = 1;
417*da2e3ebdSchin 
418*da2e3ebdSchin 		/* disable all host for - entry */
419*da2e3ebdSchin 		if ('-' == ahost[0] && '\0' == ahost[1] )
420*da2e3ebdSchin 			hostvalid = 0;
421*da2e3ebdSchin 
422*da2e3ebdSchin 		/* disable all user for - entry */
423*da2e3ebdSchin 		if ('-' == user[0] && '\0' == user[1] )
424*da2e3ebdSchin 			uservalid = 0;
425*da2e3ebdSchin 
426*da2e3ebdSchin 
427*da2e3ebdSchin #ifdef YP
428*da2e3ebdSchin 		/* disable host from -hostname entry */
429*da2e3ebdSchin 		if ('-' == ahost[0] && '@' != ahost[1]
430*da2e3ebdSchin 		    && _checkhost(rhost, &ahost[1], baselen))
431*da2e3ebdSchin 			return -1;
432*da2e3ebdSchin 		/* disable host from -@netgroup entry for host */
433*da2e3ebdSchin 		if ('-' == ahost[0] && '@' == ahost[1] && '\0' != ahost[2]
434*da2e3ebdSchin 		    && _checknetgrouphost(rhost, &ahost[2], baselen))
435*da2e3ebdSchin 			return -1;
436*da2e3ebdSchin 		/* disable user from -user entry */
437*da2e3ebdSchin 		if ('\0' != *user && user[0] == '-' && user[1] != '@'
438*da2e3ebdSchin 		    && !strcmp(&user[1], ruser))
439*da2e3ebdSchin 			return -1;
440*da2e3ebdSchin 		/* disable user from -@netgroup entry for user */
441*da2e3ebdSchin 		if ('\0' != *user && user[0] == '-' && user[1] == '@'
442*da2e3ebdSchin 		    && user[2] != '\0' && _checknetgroupuser(ruser, &user[2]))
443*da2e3ebdSchin 			return -1;
444*da2e3ebdSchin 		/* enable host from +@netgroup entry for host */
445*da2e3ebdSchin 		if ('+' == ahost[0] && '@' == ahost[1] && '\0' != ahost[2])
446*da2e3ebdSchin 			hostvalid = _checknetgrouphost(rhost, &ahost[2], baselen);
447*da2e3ebdSchin 			else
448*da2e3ebdSchin 			hostvalid = _checkhost(rhost, ahost, baselen);
449*da2e3ebdSchin 		/* enable user from +@netgroup entry for user */
450*da2e3ebdSchin 		if ('\0' != *user && user[0] == '+'
451*da2e3ebdSchin 		    && user[1] == '@' && user[2] != '\0')
452*da2e3ebdSchin 			uservalid = _checknetgroupuser(ruser, &user[2]);
453*da2e3ebdSchin 			else
454*da2e3ebdSchin 			uservalid = !strcmp(ruser, *user ? user : luser);
455*da2e3ebdSchin 
456*da2e3ebdSchin 		if (hostvalid && uservalid)
457*da2e3ebdSchin 			return 0;
458*da2e3ebdSchin #else
459*da2e3ebdSchin 		hostvalid = hostvalid ? 1 : _checkhost(rhost, ahost, baselen);
460*da2e3ebdSchin 	 	uservalid = uservalid ? 1 :	!stricmp(ruser,*user ? user : luser);
461*da2e3ebdSchin 		if (hostvalid && uservalid)
462*da2e3ebdSchin 			return 0;
463*da2e3ebdSchin 
464*da2e3ebdSchin #endif /* YP */
465*da2e3ebdSchin 		hostvalid = uservalid = 0;
466*da2e3ebdSchin 	}
467*da2e3ebdSchin 	return (-1);
468*da2e3ebdSchin }
469*da2e3ebdSchin 
470*da2e3ebdSchin int
_checkhost(const char * rhost,const char * lhost,int len)471*da2e3ebdSchin _checkhost(const char *rhost, const char *lhost, int len)
472*da2e3ebdSchin {
473*da2e3ebdSchin 	static char ldomain[MAXHOSTNAMELEN + 1];
474*da2e3ebdSchin 	static char *domainp = NULL;
475*da2e3ebdSchin 	static int nodomain = 0;
476*da2e3ebdSchin 	register char *cp;
477*da2e3ebdSchin 
478*da2e3ebdSchin 	if (len == -1)
479*da2e3ebdSchin 		return(!strcmp(rhost, lhost));
480*da2e3ebdSchin 	if (strncmp(rhost, lhost, len))
481*da2e3ebdSchin 		return(0);
482*da2e3ebdSchin 	if (!strcmp(rhost, lhost))
483*da2e3ebdSchin 		return(1);
484*da2e3ebdSchin 	if (*(lhost + len) != '\0')
485*da2e3ebdSchin 		return(0);
486*da2e3ebdSchin 	if (nodomain)
487*da2e3ebdSchin 		return(0);
488*da2e3ebdSchin 	if (!domainp) {
489*da2e3ebdSchin 		if (gethostname(ldomain, sizeof(ldomain)) == -1) {
490*da2e3ebdSchin 			nodomain = 1;
491*da2e3ebdSchin 			return(0);
492*da2e3ebdSchin 		}
493*da2e3ebdSchin 		ldomain[MAXHOSTNAMELEN] = (char) 0;
494*da2e3ebdSchin 		if ((domainp = index(ldomain, '.')) == (char *)NULL) {
495*da2e3ebdSchin 			nodomain = 1;
496*da2e3ebdSchin 			return(0);
497*da2e3ebdSchin 		}
498*da2e3ebdSchin 		for (cp = ++domainp; *cp; ++cp)
499*da2e3ebdSchin 			if (isupper(*cp))
500*da2e3ebdSchin 				*cp = tolower(*cp);
501*da2e3ebdSchin 	}
502*da2e3ebdSchin 	return(!strcmp(domainp, rhost + len +1));
503*da2e3ebdSchin }
504*da2e3ebdSchin 
505*da2e3ebdSchin #ifdef YP
506*da2e3ebdSchin static int
_checknetgrouphost(const char * rhost,const char * netgr,int baselen)507*da2e3ebdSchin _checknetgrouphost(const char *rhost, const char *netgr, int baselen)
508*da2e3ebdSchin {
509*da2e3ebdSchin 	char *host, *user, *domain;
510*da2e3ebdSchin 	int status;
511*da2e3ebdSchin 
512*da2e3ebdSchin 	if (NULL == nisdomain)
513*da2e3ebdSchin 		yp_get_default_domain(&nisdomain);
514*da2e3ebdSchin 
515*da2e3ebdSchin 	setnetgrent(netgr);
516*da2e3ebdSchin 	while (1)
517*da2e3ebdSchin 	{
518*da2e3ebdSchin 		while (1 == (status = getnetgrent(&host, &user, &domain))
519*da2e3ebdSchin 		    && NULL == host
520*da2e3ebdSchin 		    && NULL != domain
521*da2e3ebdSchin 		    && 0 != strcmp(domain, nisdomain))
522*da2e3ebdSchin 			;  /* find valid host entry */
523*da2e3ebdSchin 
524*da2e3ebdSchin 		if (0 == status || NULL == host)
525*da2e3ebdSchin 		{
526*da2e3ebdSchin 			endnetgrent();
527*da2e3ebdSchin 			return 0;
528*da2e3ebdSchin 		}
529*da2e3ebdSchin 
530*da2e3ebdSchin 		if(1 == _checkhost(rhost, host, baselen))
531*da2e3ebdSchin 		{
532*da2e3ebdSchin 			endnetgrent();
533*da2e3ebdSchin 			return 1;
534*da2e3ebdSchin 		}
535*da2e3ebdSchin 	}
536*da2e3ebdSchin }
537*da2e3ebdSchin 
538*da2e3ebdSchin static int
_checknetgroupuser(const char * ruser,const char * netgr)539*da2e3ebdSchin _checknetgroupuser(const char *ruser, const char *netgr)
540*da2e3ebdSchin {
541*da2e3ebdSchin 	char *host, *user, *domain;
542*da2e3ebdSchin 	int status;
543*da2e3ebdSchin 
544*da2e3ebdSchin 	if (NULL == nisdomain)
545*da2e3ebdSchin 		yp_get_default_domain(&nisdomain);
546*da2e3ebdSchin 
547*da2e3ebdSchin 	setnetgrent(netgr);
548*da2e3ebdSchin 	while (1)
549*da2e3ebdSchin 	{
550*da2e3ebdSchin 		while (1 == (status = getnetgrent(&host, &user, &domain))
551*da2e3ebdSchin 		    && NULL == user
552*da2e3ebdSchin 		    && NULL != domain
553*da2e3ebdSchin 		    && 0 != strcmp(domain, nisdomain))
554*da2e3ebdSchin 			;  /* find valid user entry */
555*da2e3ebdSchin 
556*da2e3ebdSchin 		if (0 == status || NULL == user)
557*da2e3ebdSchin 		{
558*da2e3ebdSchin 			endnetgrent();
559*da2e3ebdSchin 			return 0;
560*da2e3ebdSchin 		}
561*da2e3ebdSchin 
562*da2e3ebdSchin 		if(0 == strcmp(ruser, user))
563*da2e3ebdSchin 		{
564*da2e3ebdSchin 			endnetgrent();
565*da2e3ebdSchin 			return 1;
566*da2e3ebdSchin 		}
567*da2e3ebdSchin 	}
568*da2e3ebdSchin }
569*da2e3ebdSchin #endif /* YP */
570*da2e3ebdSchin 
571*da2e3ebdSchin #endif
572