174462Salfred/*	$NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $	*/
274462Salfred
3261057Smav/*-
4261057Smav * Copyright (c) 2009, Sun Microsystems, Inc.
5261057Smav * All rights reserved.
61901Swollman *
7261057Smav * Redistribution and use in source and binary forms, with or without
8261057Smav * modification, are permitted provided that the following conditions are met:
9261057Smav * - Redistributions of source code must retain the above copyright notice,
10261057Smav *   this list of conditions and the following disclaimer.
11261057Smav * - Redistributions in binary form must reproduce the above copyright notice,
12261057Smav *   this list of conditions and the following disclaimer in the documentation
13261057Smav *   and/or other materials provided with the distribution.
14261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its
15261057Smav *   contributors may be used to endorse or promote products derived
16261057Smav *   from this software without specific prior written permission.
17261057Smav *
18261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28261057Smav * POSSIBILITY OF SUCH DAMAGE.
291901Swollman */
301901Swollman
311901Swollman#if defined(LIBC_SCCS) && !defined(lint)
3274462Salfredstatic char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
331901Swollman#endif
3492990Sobrien#include <sys/cdefs.h>
3592990Sobrien__FBSDID("$FreeBSD$");
361901Swollman
371901Swollman/*
381901Swollman * Copyright (c) 1984 by Sun Microsystems, Inc.
391901Swollman */
401901Swollman
41158115Sume#include <sys/param.h>
4274462Salfred#include <sys/types.h>
43158115Sume#include <sys/socket.h>
4474462Salfred#include <arpa/inet.h>
4574462Salfred#include <assert.h>
46158115Sume#include <errno.h>
47158115Sume#include <nsswitch.h>
48158115Sume#include <netinet/in.h>
491901Swollman#include <stdio.h>
50158115Sume#include <string.h>
51158115Sume#include <stdarg.h>
5211666Sphk#include <stdlib.h>
531901Swollman#include <rpc/rpc.h>
541901Swollman#ifdef YP
551901Swollman#include <rpcsvc/yp_prot.h>
561901Swollman#include <rpcsvc/ypclnt.h>
571901Swollman#endif
58158115Sume#include <unistd.h>
59158115Sume#include "namespace.h"
60158115Sume#include "reentrant.h"
6174462Salfred#include "un-namespace.h"
62111618Snectar#include "libc_private.h"
63158115Sume#include "nss_tls.h"
64158115Sume#ifdef NS_CACHING
65158115Sume#include "nscache.h"
66158115Sume#endif
671901Swollman
68158115Sume#define	RPCDB	"/etc/rpc"
69158115Sume
70158115Sume/* nsswitch declarations */
71158115Sumeenum constants
72158115Sume{
73158115Sume	SETRPCENT = 1,
74158115Sume	ENDRPCENT = 2,
75158115Sume	RPCENT_STORAGE_INITIAL	= 1 << 10, /* 1 KByte */
76158115Sume	RPCENT_STORAGE_MAX	= 1 << 20, /* 1 MByte */
77158115Sume};
78158115Sume
79158115Sumestatic const ns_src defaultsrc[] = {
80158115Sume	{ NSSRC_FILES, NS_SUCCESS },
81158115Sume#ifdef YP
82158115Sume	{ NSSRC_NIS, NS_SUCCESS },
83158115Sume#endif
84158115Sume	{ NULL, 0 }
85158115Sume};
86158115Sume
87158115Sume/* files backend declarations */
88158115Sumestruct files_state {
89158115Sume	FILE	*fp;
901901Swollman	int	stayopen;
91158115Sume};
92158115Sume
93158115Sumestatic	int	files_rpcent(void *, void *, va_list);
94158115Sumestatic	int	files_setrpcent(void *, void *, va_list);
95158115Sume
96158115Sumestatic	void	files_endstate(void *);
97158115SumeNSS_TLS_HANDLING(files);
98158115Sume
99158115Sume/* nis backend declarations */
100158115Sume#ifdef YP
101158115Sumestruct nis_state {
102158115Sume	char	domain[MAXHOSTNAMELEN];
1031901Swollman	char	*current;
1041901Swollman	int	currentlen;
105158115Sume	int	stepping;
106158115Sume	int	no_name_map;
107158115Sume};
108158115Sume
109158115Sumestatic	int	nis_rpcent(void *, void *, va_list);
110158115Sumestatic	int	nis_setrpcent(void *, void *, va_list);
111158115Sume
112158115Sumestatic	void	nis_endstate(void *);
113158115SumeNSS_TLS_HANDLING(nis);
1141901Swollman#endif
1151901Swollman
116158115Sume/* get** wrappers for get**_r functions declarations */
117158115Sumestruct rpcent_state {
118158115Sume	struct rpcent	rpc;
119158115Sume	char		*buffer;
120158115Sume	size_t	bufsize;
121158115Sume};
122158115Sumestatic	void	rpcent_endstate(void *);
123158115SumeNSS_TLS_HANDLING(rpcent);
12474462Salfred
125158115Sumeunion key {
126158115Sume	const char	*name;
127158115Sume	int		number;
128158115Sume};
1291901Swollman
130158115Sumestatic int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
131158115Sume			size_t, struct rpcent **);
132158115Sumestatic int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
133158115Sume			size_t, struct rpcent **);
134158115Sumestatic int wrap_getrpcent_r(union key, struct rpcent *, char *,
135158115Sume			size_t, struct rpcent **);
136158115Sumestatic struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
137158115Sume			size_t, struct rpcent **), union key);
1381901Swollman
139158115Sume#ifdef NS_CACHING
140158115Sumestatic int rpc_id_func(char *, size_t *, va_list, void *);
141158115Sumestatic int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
142158115Sumestatic int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
143158115Sume#endif
1441901Swollman
145158115Sumestatic int
146158115Sumerpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
147158115Sume	size_t aliases_size, int *errnop)
1481901Swollman{
149158115Sume	char *cp, **q;
1501901Swollman
151158115Sume	assert(p != NULL);
152158115Sume
153158115Sume	if (*p == '#')
154158115Sume		return (-1);
155158115Sume	cp = strpbrk(p, "#\n");
156158115Sume	if (cp == NULL)
157158115Sume		return (-1);
158158115Sume	*cp = '\0';
159158115Sume	cp = strpbrk(p, " \t");
160158115Sume	if (cp == NULL)
161158115Sume		return (-1);
162158115Sume	*cp++ = '\0';
163158115Sume	/* THIS STUFF IS INTERNET SPECIFIC */
164158115Sume	rpc->r_name = p;
165158115Sume	while (*cp == ' ' || *cp == '\t')
166158115Sume		cp++;
167158115Sume	rpc->r_number = atoi(cp);
168158115Sume	q = rpc->r_aliases = r_aliases;
169158115Sume	cp = strpbrk(cp, " \t");
170158115Sume	if (cp != NULL)
171158115Sume		*cp++ = '\0';
172158115Sume	while (cp && *cp) {
173158115Sume		if (*cp == ' ' || *cp == '\t') {
174158115Sume			cp++;
175158115Sume			continue;
176158115Sume		}
177158115Sume		if (q < &(r_aliases[aliases_size - 1]))
178158115Sume			*q++ = cp;
179158115Sume		else {
180158115Sume			*errnop = ERANGE;
181158115Sume			return -1;
182158115Sume		}
183158115Sume
184158115Sume		cp = strpbrk(cp, " \t");
185158115Sume		if (cp != NULL)
186158115Sume			*cp++ = '\0';
1871901Swollman	}
188158115Sume	*q = NULL;
189158115Sume	return 0;
1901901Swollman}
1911901Swollman
192158115Sume/* files backend implementation */
193158115Sumestatic	void
194158115Sumefiles_endstate(void *p)
195158115Sume{
196158115Sume	FILE * f;
197158115Sume
198158115Sume	if (p == NULL)
199158115Sume		return;
200158115Sume
201158115Sume	f = ((struct files_state *)p)->fp;
202158115Sume	if (f != NULL)
203158115Sume		fclose(f);
204158115Sume
205158115Sume	free(p);
206158115Sume}
207158115Sume
208158115Sumestatic int
209158115Sumefiles_rpcent(void *retval, void *mdata, va_list ap)
210158115Sume{
211158115Sume	char *name;
21274462Salfred	int number;
213158115Sume	struct rpcent *rpc;
214158115Sume	char *buffer;
215158115Sume	size_t bufsize;
216158115Sume	int *errnop;
217158115Sume
218158115Sume	char *line;
219158115Sume	size_t linesize;
220158115Sume	char **aliases;
221158115Sume	int aliases_size;
222158115Sume	char **rp;
223158115Sume
224158115Sume	struct files_state	*st;
225158115Sume	int rv;
226158115Sume	int stayopen;
227158115Sume	enum nss_lookup_type how;
228158115Sume
229158115Sume	how = (enum nss_lookup_type)mdata;
230158115Sume	switch (how)
231158115Sume	{
232158115Sume	case nss_lt_name:
233158115Sume		name = va_arg(ap, char *);
234158115Sume		break;
235158115Sume	case nss_lt_id:
236158115Sume		number = va_arg(ap, int);
237158115Sume		break;
238158115Sume	case nss_lt_all:
239158115Sume		break;
240158115Sume	default:
241158115Sume		return (NS_NOTFOUND);
242158115Sume	}
243158115Sume
244158115Sume	rpc = va_arg(ap, struct rpcent *);
245158115Sume	buffer = va_arg(ap, char *);
246158115Sume	bufsize = va_arg(ap, size_t);
247158115Sume	errnop = va_arg(ap, int *);
248158115Sume
249158115Sume	*errnop = files_getstate(&st);
250158115Sume	if (*errnop != 0)
251158115Sume		return (NS_UNAVAIL);
252158115Sume
253158115Sume	if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
254158115Sume		*errnop = errno;
255158115Sume		return (NS_UNAVAIL);
256158115Sume	}
257158115Sume
258158115Sume	if (how == nss_lt_all)
259158115Sume		stayopen = 1;
260158115Sume	else {
261158115Sume		rewind(st->fp);
262158115Sume		stayopen = st->stayopen;
263158115Sume	}
264158115Sume
265158115Sume	do {
266158115Sume		if ((line = fgetln(st->fp, &linesize)) == NULL) {
267158115Sume			*errnop = errno;
268158115Sume			rv = NS_RETURN;
269158115Sume			break;
270158115Sume		}
271158115Sume
272158115Sume		if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
273158115Sume			*errnop = ERANGE;
274158115Sume			rv = NS_RETURN;
275158115Sume			break;
276158115Sume		}
277158115Sume
278158115Sume		aliases = (char **)_ALIGN(&buffer[linesize+1]);
279158115Sume		aliases_size = (buffer + bufsize -
280158115Sume			(char *)aliases)/sizeof(char *);
281158115Sume		if (aliases_size < 1) {
282158115Sume			*errnop = ERANGE;
283158115Sume			rv = NS_RETURN;
284158115Sume			break;
285158115Sume		}
286158115Sume
287158115Sume		memcpy(buffer, line, linesize);
288158115Sume		buffer[linesize] = '\0';
289158115Sume
290158115Sume		rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
291158115Sume		if (rv != 0) {
292158115Sume			if (*errnop == 0) {
293158115Sume				rv = NS_NOTFOUND;
294158115Sume				continue;
295158115Sume			}
296158115Sume			else {
297158115Sume				rv = NS_RETURN;
298158115Sume				break;
299158115Sume			}
300158115Sume		}
301158115Sume
302158115Sume		switch (how)
303158115Sume		{
304158115Sume		case nss_lt_name:
305158115Sume			if (strcmp(rpc->r_name, name) == 0)
306158115Sume				goto done;
307158115Sume			for (rp = rpc->r_aliases; *rp != NULL; rp++) {
308158115Sume				if (strcmp(*rp, name) == 0)
309158115Sume					goto done;
310158115Sume			}
311158115Sume			rv = NS_NOTFOUND;
312158115Sume			continue;
313158115Sumedone:
314158115Sume			rv = NS_SUCCESS;
315158115Sume			break;
316158115Sume		case nss_lt_id:
317158115Sume			rv = (rpc->r_number == number) ? NS_SUCCESS :
318158115Sume				NS_NOTFOUND;
319158115Sume			break;
320158115Sume		case nss_lt_all:
321158115Sume			rv = NS_SUCCESS;
322158115Sume			break;
323158115Sume		}
324158115Sume
325158115Sume	} while (!(rv & NS_TERMINATE));
326158115Sume
327158115Sume	if (!stayopen && st->fp!=NULL) {
328158115Sume		fclose(st->fp);
329158115Sume		st->fp = NULL;
330158115Sume	}
331158115Sume
332158115Sume	if ((rv == NS_SUCCESS) && (retval != NULL))
333158115Sume		*((struct rpcent **)retval) = rpc;
334158115Sume
335158115Sume	return (rv);
336158115Sume}
337158115Sume
338158115Sumestatic int
339158115Sumefiles_setrpcent(void *retval, void *mdata, va_list ap)
3401901Swollman{
341158115Sume	struct files_state	*st;
342158115Sume	int	rv;
343158115Sume	int	f;
3441901Swollman
345158115Sume	rv = files_getstate(&st);
346158115Sume	if (rv != 0)
347158115Sume		return (NS_UNAVAIL);
34874462Salfred
349158115Sume	switch ((enum constants)mdata)
350158115Sume	{
351158115Sume	case SETRPCENT:
352158115Sume		f = va_arg(ap,int);
353158115Sume		if (st->fp == NULL)
354158115Sume			st->fp = fopen(RPCDB, "r");
355158115Sume		else
356158115Sume			rewind(st->fp);
357158115Sume		st->stayopen |= f;
358158115Sume		break;
359158115Sume	case ENDRPCENT:
360158115Sume		if (st->fp != NULL) {
361158115Sume			fclose(st->fp);
362158115Sume			st->fp = NULL;
363158115Sume		}
364158115Sume		st->stayopen = 0;
365158115Sume		break;
366158115Sume	default:
367158115Sume		break;
368158115Sume	}
369158115Sume
370158115Sume	return (NS_UNAVAIL);
371158115Sume}
372158115Sume
373158115Sume/* nis backend implementation */
374158115Sume#ifdef YP
375158115Sumestatic 	void
376158115Sumenis_endstate(void *p)
377158115Sume{
378158115Sume	if (p == NULL)
379158115Sume		return;
380158115Sume
381158115Sume	free(((struct nis_state *)p)->current);
382158115Sume	free(p);
383158115Sume}
384158115Sume
385158115Sumestatic int
386158115Sumenis_rpcent(void *retval, void *mdata, va_list ap)
387158115Sume{
388158115Sume	char		*name;
389158115Sume	int		number;
390158115Sume	struct rpcent	*rpc;
391158115Sume	char		*buffer;
392158115Sume	size_t	bufsize;
393158115Sume	int		*errnop;
394158115Sume
395158115Sume	char		**rp;
396158115Sume	char		**aliases;
397158115Sume	int		aliases_size;
398158115Sume
399158115Sume	char	*lastkey;
400158115Sume	char	*resultbuf;
401158115Sume	int	resultbuflen;
402158115Sume	char	buf[YPMAXRECORD + 2];
403158115Sume
404158115Sume	struct nis_state	*st;
405158115Sume	int		rv;
406158115Sume	enum nss_lookup_type	how;
407158115Sume	int	no_name_active;
408158115Sume
409158115Sume	how = (enum nss_lookup_type)mdata;
410158115Sume	switch (how)
411158115Sume	{
412158115Sume	case nss_lt_name:
413158115Sume		name = va_arg(ap, char *);
414158115Sume		break;
415158115Sume	case nss_lt_id:
416158115Sume		number = va_arg(ap, int);
417158115Sume		break;
418158115Sume	case nss_lt_all:
419158115Sume		break;
420158115Sume	default:
421158115Sume		return (NS_NOTFOUND);
422158115Sume	}
423158115Sume
424158115Sume	rpc = va_arg(ap, struct rpcent *);
425158115Sume	buffer = va_arg(ap, char *);
426158115Sume	bufsize = va_arg(ap, size_t);
427158115Sume	errnop = va_arg(ap, int *);
428158115Sume
429158115Sume	*errnop = nis_getstate(&st);
430158115Sume	if (*errnop != 0)
431158115Sume		return (NS_UNAVAIL);
432158115Sume
433158115Sume	if (st->domain[0] == '\0') {
434158115Sume		if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
435158115Sume			*errnop = errno;
436158115Sume			return (NS_UNAVAIL);
437158115Sume		}
438158115Sume	}
439158115Sume
440158115Sume	no_name_active = 0;
441158115Sume	do {
442158115Sume		switch (how)
443158115Sume		{
444158115Sume		case nss_lt_name:
445158115Sume			if (!st->no_name_map)
446158115Sume			{
447158115Sume				snprintf(buf, sizeof buf, "%s", name);
448158115Sume				rv = yp_match(st->domain, "rpc.byname", buf,
449158115Sume			    		strlen(buf), &resultbuf, &resultbuflen);
450158115Sume
451158115Sume				switch (rv) {
452158115Sume				case 0:
453158115Sume					break;
454158115Sume				case YPERR_MAP:
455158115Sume					st->stepping = 0;
456158115Sume					no_name_active = 1;
457158115Sume					how = nss_lt_all;
458158115Sume
459158115Sume					rv = NS_NOTFOUND;
460158115Sume					continue;
461158115Sume				default:
462158115Sume					rv = NS_NOTFOUND;
463158115Sume					goto fin;
464158115Sume				}
465158115Sume			} else {
466158115Sume				st->stepping = 0;
467158115Sume				no_name_active = 1;
468158115Sume				how = nss_lt_all;
469158115Sume
470158115Sume				rv = NS_NOTFOUND;
471158115Sume				continue;
472158115Sume			}
473158115Sume		break;
474158115Sume		case nss_lt_id:
475158115Sume			snprintf(buf, sizeof buf, "%d", number);
476158115Sume			if (yp_match(st->domain, "rpc.bynumber", buf,
477158115Sume			    	strlen(buf), &resultbuf, &resultbuflen)) {
478158115Sume				rv = NS_NOTFOUND;
479158115Sume				goto fin;
480158115Sume			}
4811901Swollman			break;
482158115Sume		case nss_lt_all:
483158115Sume				if (!st->stepping) {
484158115Sume					rv = yp_first(st->domain, "rpc.bynumber",
485158115Sume				    		&st->current,
486158115Sume						&st->currentlen, &resultbuf,
487158115Sume				    		&resultbuflen);
488158115Sume					if (rv) {
489158115Sume						rv = NS_NOTFOUND;
490158115Sume						goto fin;
491158115Sume					}
492158115Sume					st->stepping = 1;
493158115Sume				} else {
494158115Sume					lastkey = st->current;
495158115Sume					rv = yp_next(st->domain, "rpc.bynumber",
496158115Sume				    		st->current,
497158115Sume						st->currentlen, &st->current,
498158115Sume				    		&st->currentlen,
499158115Sume						&resultbuf,	&resultbuflen);
500158115Sume					free(lastkey);
501158115Sume					if (rv) {
502158115Sume						st->stepping = 0;
503158115Sume						rv = NS_NOTFOUND;
504158115Sume						goto fin;
505158115Sume					}
506158115Sume				}
507158115Sume			break;
508158115Sume		}
509158115Sume
510158115Sume		/* we need a room for additional \n symbol */
511158115Sume		if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
512158115Sume		    sizeof(char *)) {
513158115Sume			*errnop = ERANGE;
514158115Sume			rv = NS_RETURN;
515158115Sume			break;
516158115Sume		}
517158115Sume
518158115Sume		aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
519158115Sume		aliases_size = (buffer + bufsize - (char *)aliases) /
520158115Sume			sizeof(char *);
521158115Sume		if (aliases_size < 1) {
522158115Sume			*errnop = ERANGE;
523158115Sume			rv = NS_RETURN;
524158115Sume			break;
525158115Sume		}
526158115Sume
527158115Sume		/*
528158115Sume		 * rpcent_unpack expects lines terminated with \n -- make it happy
529158115Sume		 */
530158115Sume		memcpy(buffer, resultbuf, resultbuflen);
531158115Sume		buffer[resultbuflen] = '\n';
532158115Sume		buffer[resultbuflen+1] = '\0';
533158115Sume		free(resultbuf);
534158115Sume
535158115Sume		if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
536158115Sume		    errnop) != 0) {
537158115Sume			if (*errnop == 0)
538158115Sume				rv = NS_NOTFOUND;
539158115Sume			else
540158115Sume				rv = NS_RETURN;
541158115Sume		} else {
542158115Sume			if ((how == nss_lt_all) && (no_name_active != 0)) {
543158115Sume				if (strcmp(rpc->r_name, name) == 0)
544158115Sume					goto done;
545158115Sume				for (rp = rpc->r_aliases; *rp != NULL; rp++) {
546158115Sume					if (strcmp(*rp, name) == 0)
547158115Sume						goto done;
548158115Sume				}
549158115Sume				rv = NS_NOTFOUND;
550158115Sume				continue;
551158115Sumedone:
552158115Sume				rv = NS_SUCCESS;
553158115Sume			} else
554158115Sume				rv = NS_SUCCESS;
555158115Sume		}
556158115Sume
557158115Sume	} while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
558158115Sume
559158115Sumefin:
560158115Sume	if ((rv == NS_SUCCESS) && (retval != NULL))
561158115Sume		*((struct rpcent **)retval) = rpc;
562158115Sume
563158115Sume	return (rv);
564158115Sume}
565158115Sume
566158115Sumestatic int
567158115Sumenis_setrpcent(void *retval, void *mdata, va_list ap)
568158115Sume{
569158115Sume	struct nis_state	*st;
570158115Sume	int	rv;
571158115Sume
572158115Sume	rv = nis_getstate(&st);
573158115Sume	if (rv != 0)
574158115Sume		return (NS_UNAVAIL);
575158115Sume
576158115Sume	switch ((enum constants)mdata)
577158115Sume	{
578158115Sume	case SETRPCENT:
579158115Sume	case ENDRPCENT:
580158115Sume		free(st->current);
581158115Sume		st->current = NULL;
582158115Sume		st->stepping = 0;
583158115Sume		break;
584158115Sume	default:
585158115Sume		break;
5861901Swollman	}
587158115Sume
588158115Sume	return (NS_UNAVAIL);
5891901Swollman}
590158115Sume#endif
5911901Swollman
592158115Sume#ifdef NS_CACHING
593158115Sumestatic int
594158115Sumerpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
595158115Sume{
5961901Swollman	char *name;
597158115Sume	int rpc;
598158115Sume
599158115Sume	size_t desired_size, size;
600158115Sume	enum nss_lookup_type lookup_type;
601158115Sume	int res = NS_UNAVAIL;
602158115Sume
603158115Sume	lookup_type = (enum nss_lookup_type)cache_mdata;
604158115Sume	switch (lookup_type) {
605158115Sume	case nss_lt_name:
606158115Sume		name = va_arg(ap, char *);
607158115Sume
608158115Sume		size = strlen(name);
609158115Sume		desired_size = sizeof(enum nss_lookup_type) + size + 1;
610158115Sume		if (desired_size > *buffer_size) {
611158115Sume			res = NS_RETURN;
612158115Sume			goto fin;
613158115Sume		}
614158115Sume
615158115Sume		memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
616158115Sume		memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
617158115Sume
618158115Sume		res = NS_SUCCESS;
619158115Sume		break;
620158115Sume	case nss_lt_id:
621158115Sume		rpc = va_arg(ap, int);
622158115Sume
623158115Sume		desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
624158115Sume		if (desired_size > *buffer_size) {
625158115Sume			res = NS_RETURN;
626158115Sume			goto fin;
627158115Sume		}
628158115Sume
629158115Sume		memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
630158115Sume		memcpy(buffer + sizeof(enum nss_lookup_type), &rpc,
631158115Sume		    sizeof(int));
632158115Sume
633158115Sume		res = NS_SUCCESS;
634158115Sume		break;
635158115Sume	default:
636158115Sume		/* should be unreachable */
637158115Sume		return (NS_UNAVAIL);
638158115Sume	}
639158115Sume
640158115Sumefin:
641158115Sume	*buffer_size = desired_size;
642158115Sume	return (res);
643158115Sume}
644158115Sume
645158115Sumestatic int
646158115Sumerpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
647158115Sume    void *cache_mdata)
6481901Swollman{
649158115Sume	char *name;
650158115Sume	int num;
651158115Sume	struct rpcent *rpc;
652158115Sume	char *orig_buf;
653158115Sume	size_t orig_buf_size;
6541901Swollman
655158115Sume	struct rpcent new_rpc;
656158115Sume	size_t desired_size, size, aliases_size;
657158115Sume	char *p;
658158115Sume	char **alias;
65974462Salfred
660158115Sume	switch ((enum nss_lookup_type)cache_mdata) {
661158115Sume	case nss_lt_name:
662158115Sume		name = va_arg(ap, char *);
663158115Sume		break;
664158115Sume	case nss_lt_id:
665158115Sume		num = va_arg(ap, int);
666158115Sume		break;
667158115Sume	case nss_lt_all:
668158115Sume		break;
669158115Sume	default:
670158115Sume		/* should be unreachable */
671158115Sume		return (NS_UNAVAIL);
672158115Sume	}
673158115Sume
674158115Sume	rpc = va_arg(ap, struct rpcent *);
675158115Sume	orig_buf = va_arg(ap, char *);
676158115Sume	orig_buf_size = va_arg(ap, size_t);
677158115Sume
678158115Sume	desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *);
679158115Sume	if (rpc->r_name != NULL)
680158115Sume		desired_size += strlen(rpc->r_name) + 1;
681158115Sume
682158115Sume	if (rpc->r_aliases != NULL) {
683158115Sume		aliases_size = 0;
684158115Sume		for (alias = rpc->r_aliases; *alias; ++alias) {
685158115Sume			desired_size += strlen(*alias) + 1;
686158115Sume			++aliases_size;
6871901Swollman		}
688158115Sume
689158115Sume		desired_size += _ALIGNBYTES + (aliases_size + 1) *
690158115Sume		    sizeof(char *);
6911901Swollman	}
692158115Sume
693158115Sume	if (*buffer_size < desired_size) {
694158115Sume		/* this assignment is here for future use */
695158115Sume		*buffer_size = desired_size;
696158115Sume		return (NS_RETURN);
697158115Sume	}
698158115Sume
699199787Swollman	new_rpc = *rpc;
700158115Sume
701158115Sume	*buffer_size = desired_size;
702158115Sume	memset(buffer, 0, desired_size);
703158115Sume	p = buffer + sizeof(struct rpcent) + sizeof(char *);
704158115Sume	memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *));
705158115Sume	p = (char *)_ALIGN(p);
706158115Sume
707158115Sume	if (new_rpc.r_name != NULL) {
708158115Sume		size = strlen(new_rpc.r_name);
709158115Sume		memcpy(p, new_rpc.r_name, size);
710158115Sume		new_rpc.r_name = p;
711158115Sume		p += size + 1;
712158115Sume	}
713158115Sume
714158115Sume	if (new_rpc.r_aliases != NULL) {
715158115Sume		p = (char *)_ALIGN(p);
716158115Sume		memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size);
717158115Sume		new_rpc.r_aliases = (char **)p;
718158115Sume		p += sizeof(char *) * (aliases_size + 1);
719158115Sume
720158115Sume		for (alias = new_rpc.r_aliases; *alias; ++alias) {
721158115Sume			size = strlen(*alias);
722158115Sume			memcpy(p, *alias, size);
723158115Sume			*alias = p;
724158115Sume			p += size + 1;
725158115Sume		}
726158115Sume	}
727158115Sume
728158115Sume	memcpy(buffer, &new_rpc, sizeof(struct rpcent));
729158115Sume	return (NS_SUCCESS);
7301901Swollman}
7311901Swollman
732158115Sumestatic int
733158115Sumerpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
734158115Sume    void *cache_mdata)
7351901Swollman{
736158115Sume	char *name;
737158115Sume	int num;
738158115Sume	struct rpcent *rpc;
739158115Sume	char *orig_buf;
740158115Sume	size_t orig_buf_size;
741158115Sume	int *ret_errno;
7421901Swollman
743158115Sume	char *p;
744158115Sume	char **alias;
745158115Sume
746158115Sume	switch ((enum nss_lookup_type)cache_mdata) {
747158115Sume	case nss_lt_name:
748158115Sume		name = va_arg(ap, char *);
749158115Sume		break;
750158115Sume	case nss_lt_id:
751158115Sume		num = va_arg(ap, int);
752158115Sume		break;
753158115Sume	case nss_lt_all:
754158115Sume		break;
755158115Sume	default:
756158115Sume		/* should be unreachable */
757158115Sume		return (NS_UNAVAIL);
758158115Sume	}
759158115Sume
760158115Sume	rpc = va_arg(ap, struct rpcent *);
761158115Sume	orig_buf = va_arg(ap, char *);
762158115Sume	orig_buf_size = va_arg(ap, size_t);
763158115Sume	ret_errno = va_arg(ap, int *);
764158115Sume
765158115Sume	if (orig_buf_size <
766158115Sume	    buffer_size - sizeof(struct rpcent) - sizeof(char *)) {
767158115Sume		*ret_errno = ERANGE;
768158115Sume		return (NS_RETURN);
769158115Sume	}
770158115Sume
771158115Sume	memcpy(rpc, buffer, sizeof(struct rpcent));
772158115Sume	memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *));
773158115Sume
774158115Sume	orig_buf = (char *)_ALIGN(orig_buf);
775158115Sume	memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) +
776158115Sume	    _ALIGN(p) - (size_t)p,
777158115Sume	    buffer_size - sizeof(struct rpcent) - sizeof(char *) -
778158115Sume	    _ALIGN(p) + (size_t)p);
779158115Sume	p = (char *)_ALIGN(p);
780158115Sume
781158115Sume	NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *);
782158115Sume	if (rpc->r_aliases != NULL) {
783158115Sume		NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **);
784158115Sume
785158115Sume		for (alias = rpc->r_aliases	; *alias; ++alias)
786158115Sume			NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
787158115Sume	}
788158115Sume
789158115Sume	if (retval != NULL)
790158115Sume		*((struct rpcent **)retval) = rpc;
791158115Sume
792158115Sume	return (NS_SUCCESS);
793158115Sume}
794158115Sume
795158115SumeNSS_MP_CACHE_HANDLING(rpc);
796158115Sume#endif /* NS_CACHING */
797158115Sume
798158115Sume
799158115Sume/* get**_r functions implementation */
800158115Sumestatic int
801158115Sumegetrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
802158115Sume	size_t bufsize, struct rpcent **result)
803158115Sume{
804158115Sume#ifdef NS_CACHING
805158115Sume	static const nss_cache_info cache_info =
806158115Sume    		NS_COMMON_CACHE_INFO_INITIALIZER(
807158115Sume		rpc, (void *)nss_lt_name,
808158115Sume		rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
809158115Sume#endif
810158115Sume	static const ns_dtab dtab[] = {
811158115Sume		{ NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
812158115Sume#ifdef YP
813158115Sume		{ NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
814158115Sume#endif
815158115Sume#ifdef NS_CACHING
816158115Sume		NS_CACHE_CB(&cache_info)
817158115Sume#endif
818158115Sume		{ NULL, NULL, NULL }
819158115Sume	};
820158115Sume	int rv, ret_errno;
821158115Sume
822158115Sume	ret_errno = 0;
823158115Sume	*result = NULL;
824158115Sume	rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
825158115Sume	    name, rpc, buffer, bufsize, &ret_errno);
826158115Sume
827158115Sume	if (rv == NS_SUCCESS)
828158115Sume		return (0);
8291901Swollman	else
830158115Sume		return (ret_errno);
8311901Swollman}
8321901Swollman
833158115Sumestatic int
834158115Sumegetrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
835158115Sume	size_t bufsize, struct rpcent **result)
8361901Swollman{
837158115Sume#ifdef NS_CACHING
838158115Sume	static const nss_cache_info cache_info =
839158115Sume    		NS_COMMON_CACHE_INFO_INITIALIZER(
840158115Sume		rpc, (void *)nss_lt_id,
841158115Sume		rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
842158115Sume#endif
843158115Sume	static const ns_dtab dtab[] = {
844158115Sume		{ NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
845158115Sume#ifdef YP
846158115Sume		{ NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
847158115Sume#endif
848158115Sume#ifdef NS_CACHING
849158115Sume		NS_CACHE_CB(&cache_info)
850158115Sume#endif
851158115Sume		{ NULL, NULL, NULL }
852158115Sume	};
853158115Sume	int rv, ret_errno;
8541901Swollman
855158115Sume	ret_errno = 0;
856158115Sume	*result = NULL;
857158115Sume	rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
858158115Sume	    number, rpc, buffer, bufsize, &ret_errno);
859158115Sume
860158115Sume	if (rv == NS_SUCCESS)
861158115Sume		return (0);
862158115Sume	else
863158115Sume		return (ret_errno);
864158115Sume}
865158115Sume
866158115Sumestatic int
867158115Sumegetrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
868158115Sume	struct rpcent **result)
869158115Sume{
870158115Sume#ifdef NS_CACHING
871158115Sume	static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
872158115Sume		rpc, (void *)nss_lt_all,
873158115Sume		rpc_marshal_func, rpc_unmarshal_func);
874158115Sume#endif
875158115Sume	static const ns_dtab dtab[] = {
876158115Sume		{ NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
877158115Sume#ifdef YP
878158115Sume		{ NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
879158115Sume#endif
880158115Sume#ifdef NS_CACHING
881158115Sume		NS_CACHE_CB(&cache_info)
882158115Sume#endif
883158115Sume		{ NULL, NULL, NULL }
884158115Sume	};
885158115Sume	int rv, ret_errno;
886158115Sume
887158115Sume	ret_errno = 0;
888158115Sume	*result = NULL;
889158115Sume	rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
890158115Sume	    rpc, buffer, bufsize, &ret_errno);
891158115Sume
892158115Sume	if (rv == NS_SUCCESS)
893158115Sume		return (0);
894158115Sume	else
895158115Sume		return (ret_errno);
896158115Sume}
897158115Sume
898158115Sume/* get** wrappers for get**_r functions implementation */
899158115Sumestatic 	void
900158115Sumerpcent_endstate(void *p)
901158115Sume{
902158115Sume	if (p == NULL)
9031901Swollman		return;
904158115Sume
905158115Sume	free(((struct rpcent_state *)p)->buffer);
906158115Sume	free(p);
907158115Sume}
908158115Sume
909158115Sumestatic	int
910158115Sumewrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer,
911158115Sume    size_t bufsize, struct rpcent **res)
912158115Sume{
913158115Sume	return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
914158115Sume}
915158115Sume
916158115Sumestatic	int
917158115Sumewrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer,
918158115Sume    size_t bufsize, struct rpcent **res)
919158115Sume{
920158115Sume	return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
921158115Sume}
922158115Sume
923158115Sumestatic	int
924158115Sumewrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer,
925158115Sume    size_t bufsize, struct rpcent **res)
926158115Sume{
927158115Sume	return (getrpcent_r(rpc, buffer, bufsize, res));
928158115Sume}
929158115Sume
930158115Sumestatic struct rpcent *
931158115Sumegetrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
932158115Sume    union key key)
933158115Sume{
934158115Sume	int		 rv;
935158115Sume	struct rpcent	*res;
936158115Sume	struct rpcent_state * st;
937158115Sume
938158115Sume	rv=rpcent_getstate(&st);
939158115Sume	if (rv != 0) {
940158115Sume		errno = rv;
941158115Sume		return NULL;
9421901Swollman	}
943158115Sume
944158115Sume	if (st->buffer == NULL) {
945158115Sume		st->buffer = malloc(RPCENT_STORAGE_INITIAL);
946158115Sume		if (st->buffer == NULL)
947158115Sume			return (NULL);
948158115Sume		st->bufsize = RPCENT_STORAGE_INITIAL;
949158115Sume	}
950158115Sume	do {
951158115Sume		rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
952158115Sume		if (res == NULL && rv == ERANGE) {
953158115Sume			free(st->buffer);
954158115Sume			if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
955158115Sume				st->buffer = NULL;
956158115Sume				errno = ERANGE;
957158115Sume				return (NULL);
958158115Sume			}
959158115Sume			st->bufsize <<= 1;
960158115Sume			st->buffer = malloc(st->bufsize);
961158115Sume			if (st->buffer == NULL)
962158115Sume				return (NULL);
963158115Sume		}
964158115Sume	} while (res == NULL && rv == ERANGE);
965158115Sume	if (rv != 0)
966158115Sume		errno = rv;
967158115Sume
968158115Sume	return (res);
9691901Swollman}
9701901Swollman
9711901Swollmanstruct rpcent *
972158115Sumegetrpcbyname(char *name)
973158115Sume{
974158115Sume	union key key;
975158115Sume
976158115Sume	key.name = name;
977158115Sume
978158115Sume	return (getrpc(wrap_getrpcbyname_r, key));
979158115Sume}
980158115Sume
981158115Sumestruct rpcent *
982158115Sumegetrpcbynumber(int number)
983158115Sume{
984158115Sume	union key key;
985158115Sume
986158115Sume	key.number = number;
987158115Sume
988158115Sume	return (getrpc(wrap_getrpcbynumber_r, key));
989158115Sume}
990158115Sume
991158115Sumestruct rpcent *
9921901Swollmangetrpcent()
9931901Swollman{
994158115Sume	union key key;
995158115Sume
996158115Sume	key.number = 0;	/* not used */
997158115Sume
998158115Sume	return (getrpc(wrap_getrpcent_r, key));
999158115Sume}
1000158115Sume
1001158115Sumevoid
1002158115Sumesetrpcent(int stayopen)
1003158115Sume{
1004158115Sume#ifdef NS_CACHING
1005158115Sume	static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1006158115Sume		rpc, (void *)nss_lt_all,
1007158115Sume		NULL, NULL);
10081901Swollman#endif
10091901Swollman
1010158115Sume	static const ns_dtab dtab[] = {
1011158115Sume		{ NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
1012158115Sume#ifdef YP
1013158115Sume		{ NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
1014158115Sume#endif
1015158115Sume#ifdef NS_CACHING
1016158115Sume		NS_CACHE_CB(&cache_info)
1017158115Sume#endif
1018158115Sume		{ NULL, NULL, NULL }
1019158115Sume	};
1020158115Sume
1021158115Sume	(void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc,
1022158115Sume		stayopen);
10231901Swollman}
10241901Swollman
1025158115Sumevoid
1026158115Sumeendrpcent()
10271901Swollman{
1028158115Sume#ifdef NS_CACHING
1029158115Sume	static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1030158115Sume		rpc, (void *)nss_lt_all,
1031158115Sume		NULL, NULL);
1032158115Sume#endif
10331901Swollman
1034158115Sume	static const ns_dtab dtab[] = {
1035158115Sume		{ NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
1036158115Sume#ifdef YP
1037158115Sume		{ NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
1038158115Sume#endif
1039158115Sume#ifdef NS_CACHING
1040158115Sume		NS_CACHE_CB(&cache_info)
1041158115Sume#endif
1042158115Sume		{ NULL, NULL, NULL }
1043158115Sume	};
104474462Salfred
1045169645Sjon	(void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc);
10461901Swollman}
1047