1 /* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */
4 * Copyright (c) 2009, Sun Microsystems, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * - Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * - Neither the name of Sun Microsystems, Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
31 #if defined(LIBC_SCCS) && !defined(lint)
32 static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
38 * Copyright (c) 1984 by Sun Microsystems, Inc.
41 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <arpa/inet.h>
48 #include <netinet/in.h>
55 #include <rpcsvc/yp_prot.h>
56 #include <rpcsvc/ypclnt.h>
59 #include "namespace.h"
60 #include "reentrant.h"
61 #include "un-namespace.h"
62 #include "libc_private.h"
68 #define RPCDB "/etc/rpc"
70 /* nsswitch declarations */
75 RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
76 RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */
79 static const ns_src defaultsrc[] = {
80 { NSSRC_FILES, NS_SUCCESS },
82 { NSSRC_NIS, NS_SUCCESS },
87 /* files backend declarations */
93 static int files_rpcent(void *, void *, va_list);
94 static int files_setrpcent(void *, void *, va_list);
96 static void files_endstate(void *);
97 NSS_TLS_HANDLING(files);
99 /* nis backend declarations */
102 char domain[MAXHOSTNAMELEN];
109 static int nis_rpcent(void *, void *, va_list);
110 static int nis_setrpcent(void *, void *, va_list);
112 static void nis_endstate(void *);
113 NSS_TLS_HANDLING(nis);
116 /* get** wrappers for get**_r functions declarations */
117 struct rpcent_state {
122 static void rpcent_endstate(void *);
123 NSS_TLS_HANDLING(rpcent);
130 static int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
131 size_t, struct rpcent **);
132 static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
133 size_t, struct rpcent **);
134 static int wrap_getrpcent_r(union key, struct rpcent *, char *,
135 size_t, struct rpcent **);
136 static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
137 size_t, struct rpcent **), union key);
140 static int rpc_id_func(char *, size_t *, va_list, void *);
141 static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
142 static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
146 rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
147 size_t aliases_size, int *errnop)
155 cp = strpbrk(p, "#\n");
159 cp = strpbrk(p, " \t");
163 /* THIS STUFF IS INTERNET SPECIFIC */
165 while (*cp == ' ' || *cp == '\t')
167 rpc->r_number = atoi(cp);
168 q = rpc->r_aliases = r_aliases;
169 cp = strpbrk(cp, " \t");
173 if (*cp == ' ' || *cp == '\t') {
177 if (q < &(r_aliases[aliases_size - 1]))
184 cp = strpbrk(cp, " \t");
192 /* files backend implementation */
194 files_endstate(void *p)
201 f = ((struct files_state *)p)->fp;
209 files_rpcent(void *retval, void *mdata, va_list ap)
224 struct files_state *st;
227 enum nss_lookup_type how;
229 how = (enum nss_lookup_type)mdata;
233 name = va_arg(ap, char *);
236 number = va_arg(ap, int);
241 return (NS_NOTFOUND);
244 rpc = va_arg(ap, struct rpcent *);
245 buffer = va_arg(ap, char *);
246 bufsize = va_arg(ap, size_t);
247 errnop = va_arg(ap, int *);
249 *errnop = files_getstate(&st);
253 if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
258 if (how == nss_lt_all)
262 stayopen = st->stayopen;
266 if ((line = fgetln(st->fp, &linesize)) == NULL) {
272 if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
278 aliases = (char **)_ALIGN(&buffer[linesize+1]);
279 aliases_size = (buffer + bufsize -
280 (char *)aliases)/sizeof(char *);
281 if (aliases_size < 1) {
287 memcpy(buffer, line, linesize);
288 buffer[linesize] = '\0';
290 rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
305 if (strcmp(rpc->r_name, name) == 0)
307 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
308 if (strcmp(*rp, name) == 0)
317 rv = (rpc->r_number == number) ? NS_SUCCESS :
325 } while (!(rv & NS_TERMINATE));
327 if (!stayopen && st->fp!=NULL) {
332 if ((rv == NS_SUCCESS) && (retval != NULL))
333 *((struct rpcent **)retval) = rpc;
339 files_setrpcent(void *retval, void *mdata, va_list ap)
341 struct files_state *st;
345 rv = files_getstate(&st);
349 switch ((enum constants)mdata)
354 st->fp = fopen(RPCDB, "r");
360 if (st->fp != NULL) {
373 /* nis backend implementation */
376 nis_endstate(void *p)
381 free(((struct nis_state *)p)->current);
386 nis_rpcent(void *retval, void *mdata, va_list ap)
402 char buf[YPMAXRECORD + 2];
404 struct nis_state *st;
406 enum nss_lookup_type how;
409 how = (enum nss_lookup_type)mdata;
413 name = va_arg(ap, char *);
416 number = va_arg(ap, int);
421 return (NS_NOTFOUND);
424 rpc = va_arg(ap, struct rpcent *);
425 buffer = va_arg(ap, char *);
426 bufsize = va_arg(ap, size_t);
427 errnop = va_arg(ap, int *);
429 *errnop = nis_getstate(&st);
433 if (st->domain[0] == '\0') {
434 if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
445 if (!st->no_name_map)
447 snprintf(buf, sizeof buf, "%s", name);
448 rv = yp_match(st->domain, "rpc.byname", buf,
449 strlen(buf), &resultbuf, &resultbuflen);
475 snprintf(buf, sizeof buf, "%d", number);
476 if (yp_match(st->domain, "rpc.bynumber", buf,
477 strlen(buf), &resultbuf, &resultbuflen)) {
484 rv = yp_first(st->domain, "rpc.bynumber",
486 &st->currentlen, &resultbuf,
494 lastkey = st->current;
495 rv = yp_next(st->domain, "rpc.bynumber",
497 st->currentlen, &st->current,
499 &resultbuf, &resultbuflen);
510 /* we need a room for additional \n symbol */
511 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
518 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
519 aliases_size = (buffer + bufsize - (char *)aliases) /
521 if (aliases_size < 1) {
528 * rpcent_unpack expects lines terminated with \n -- make it happy
530 memcpy(buffer, resultbuf, resultbuflen);
531 buffer[resultbuflen] = '\n';
532 buffer[resultbuflen+1] = '\0';
535 if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
542 if ((how == nss_lt_all) && (no_name_active != 0)) {
543 if (strcmp(rpc->r_name, name) == 0)
545 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
546 if (strcmp(*rp, name) == 0)
557 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
560 if ((rv == NS_SUCCESS) && (retval != NULL))
561 *((struct rpcent **)retval) = rpc;
567 nis_setrpcent(void *retval, void *mdata, va_list ap)
569 struct nis_state *st;
572 rv = nis_getstate(&st);
576 switch ((enum constants)mdata)
594 rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
599 size_t desired_size, size;
600 enum nss_lookup_type lookup_type;
601 int res = NS_UNAVAIL;
603 lookup_type = (enum nss_lookup_type)cache_mdata;
604 switch (lookup_type) {
606 name = va_arg(ap, char *);
609 desired_size = sizeof(enum nss_lookup_type) + size + 1;
610 if (desired_size > *buffer_size) {
615 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
616 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
621 rpc = va_arg(ap, int);
623 desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
624 if (desired_size > *buffer_size) {
629 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
630 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc,
636 /* should be unreachable */
641 *buffer_size = desired_size;
646 rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
653 size_t orig_buf_size;
655 struct rpcent new_rpc;
656 size_t desired_size, size, aliases_size;
660 switch ((enum nss_lookup_type)cache_mdata) {
662 name = va_arg(ap, char *);
665 num = va_arg(ap, int);
670 /* should be unreachable */
674 rpc = va_arg(ap, struct rpcent *);
675 orig_buf = va_arg(ap, char *);
676 orig_buf_size = va_arg(ap, size_t);
678 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *);
679 if (rpc->r_name != NULL)
680 desired_size += strlen(rpc->r_name) + 1;
682 if (rpc->r_aliases != NULL) {
684 for (alias = rpc->r_aliases; *alias; ++alias) {
685 desired_size += strlen(*alias) + 1;
689 desired_size += _ALIGNBYTES + (aliases_size + 1) *
693 if (*buffer_size < desired_size) {
694 /* this assignment is here for future use */
695 *buffer_size = desired_size;
701 *buffer_size = desired_size;
702 memset(buffer, 0, desired_size);
703 p = buffer + sizeof(struct rpcent) + sizeof(char *);
704 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *));
705 p = (char *)_ALIGN(p);
707 if (new_rpc.r_name != NULL) {
708 size = strlen(new_rpc.r_name);
709 memcpy(p, new_rpc.r_name, size);
714 if (new_rpc.r_aliases != NULL) {
715 p = (char *)_ALIGN(p);
716 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size);
717 new_rpc.r_aliases = (char **)p;
718 p += sizeof(char *) * (aliases_size + 1);
720 for (alias = new_rpc.r_aliases; *alias; ++alias) {
721 size = strlen(*alias);
722 memcpy(p, *alias, size);
728 memcpy(buffer, &new_rpc, sizeof(struct rpcent));
733 rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
740 size_t orig_buf_size;
746 switch ((enum nss_lookup_type)cache_mdata) {
748 name = va_arg(ap, char *);
751 num = va_arg(ap, int);
756 /* should be unreachable */
760 rpc = va_arg(ap, struct rpcent *);
761 orig_buf = va_arg(ap, char *);
762 orig_buf_size = va_arg(ap, size_t);
763 ret_errno = va_arg(ap, int *);
766 buffer_size - sizeof(struct rpcent) - sizeof(char *)) {
771 memcpy(rpc, buffer, sizeof(struct rpcent));
772 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *));
774 orig_buf = (char *)_ALIGN(orig_buf);
775 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) +
776 _ALIGN(p) - (size_t)p,
777 buffer_size - sizeof(struct rpcent) - sizeof(char *) -
778 _ALIGN(p) + (size_t)p);
779 p = (char *)_ALIGN(p);
781 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *);
782 if (rpc->r_aliases != NULL) {
783 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **);
785 for (alias = rpc->r_aliases ; *alias; ++alias)
786 NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
790 *((struct rpcent **)retval) = rpc;
795 NSS_MP_CACHE_HANDLING(rpc);
796 #endif /* NS_CACHING */
799 /* get**_r functions implementation */
801 getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
802 size_t bufsize, struct rpcent **result)
805 static const nss_cache_info cache_info =
806 NS_COMMON_CACHE_INFO_INITIALIZER(
807 rpc, (void *)nss_lt_name,
808 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
810 static const ns_dtab dtab[] = {
811 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
813 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
816 NS_CACHE_CB(&cache_info)
824 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
825 name, rpc, buffer, bufsize, &ret_errno);
827 if (rv == NS_SUCCESS)
834 getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
835 size_t bufsize, struct rpcent **result)
838 static const nss_cache_info cache_info =
839 NS_COMMON_CACHE_INFO_INITIALIZER(
840 rpc, (void *)nss_lt_id,
841 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
843 static const ns_dtab dtab[] = {
844 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
846 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
849 NS_CACHE_CB(&cache_info)
857 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
858 number, rpc, buffer, bufsize, &ret_errno);
860 if (rv == NS_SUCCESS)
867 getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
868 struct rpcent **result)
871 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
872 rpc, (void *)nss_lt_all,
873 rpc_marshal_func, rpc_unmarshal_func);
875 static const ns_dtab dtab[] = {
876 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
878 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
881 NS_CACHE_CB(&cache_info)
889 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
890 rpc, buffer, bufsize, &ret_errno);
892 if (rv == NS_SUCCESS)
898 /* get** wrappers for get**_r functions implementation */
900 rpcent_endstate(void *p)
905 free(((struct rpcent_state *)p)->buffer);
910 wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer,
911 size_t bufsize, struct rpcent **res)
913 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
917 wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer,
918 size_t bufsize, struct rpcent **res)
920 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
924 wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer,
925 size_t bufsize, struct rpcent **res)
927 return (getrpcent_r(rpc, buffer, bufsize, res));
930 static struct rpcent *
931 getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
936 struct rpcent_state * st;
938 rv=rpcent_getstate(&st);
944 if (st->buffer == NULL) {
945 st->buffer = malloc(RPCENT_STORAGE_INITIAL);
946 if (st->buffer == NULL)
948 st->bufsize = RPCENT_STORAGE_INITIAL;
951 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
952 if (res == NULL && rv == ERANGE) {
954 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
960 st->buffer = malloc(st->bufsize);
961 if (st->buffer == NULL)
964 } while (res == NULL && rv == ERANGE);
972 getrpcbyname(char *name)
978 return (getrpc(wrap_getrpcbyname_r, key));
982 getrpcbynumber(int number)
988 return (getrpc(wrap_getrpcbynumber_r, key));
996 key.number = 0; /* not used */
998 return (getrpc(wrap_getrpcent_r, key));
1002 setrpcent(int stayopen)
1005 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1006 rpc, (void *)nss_lt_all,
1010 static const ns_dtab dtab[] = {
1011 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
1013 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
1016 NS_CACHE_CB(&cache_info)
1018 { NULL, NULL, NULL }
1021 (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc,
1029 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1030 rpc, (void *)nss_lt_all,
1034 static const ns_dtab dtab[] = {
1035 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
1037 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
1040 NS_CACHE_CB(&cache_info)
1042 { NULL, NULL, NULL }
1045 (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc);