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