1 /* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */
4 * SPDX-License-Identifier: BSD-3-Clause
6 * Copyright (c) 2009, Sun Microsystems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * - Neither the name of Sun Microsystems, Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #if defined(LIBC_SCCS) && !defined(lint)
34 static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
40 * Copyright (c) 1984 by Sun Microsystems, Inc.
43 #include <sys/param.h>
44 #include <sys/socket.h>
45 #include <arpa/inet.h>
49 #include <netinet/in.h>
56 #include <rpcsvc/yp_prot.h>
57 #include <rpcsvc/ypclnt.h>
60 #include "namespace.h"
61 #include "reentrant.h"
62 #include "un-namespace.h"
63 #include "libc_private.h"
69 #define RPCDB "/etc/rpc"
71 /* nsswitch declarations */
76 RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
77 RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */
80 static const ns_src defaultsrc[] = {
81 { NSSRC_FILES, NS_SUCCESS },
83 { NSSRC_NIS, NS_SUCCESS },
88 /* files backend declarations */
94 static int files_rpcent(void *, void *, va_list);
95 static int files_setrpcent(void *, void *, va_list);
97 static void files_endstate(void *);
98 NSS_TLS_HANDLING(files);
100 /* nis backend declarations */
103 char domain[MAXHOSTNAMELEN];
110 static int nis_rpcent(void *, void *, va_list);
111 static int nis_setrpcent(void *, void *, va_list);
113 static void nis_endstate(void *);
114 NSS_TLS_HANDLING(nis);
117 /* get** wrappers for get**_r functions declarations */
118 struct rpcent_state {
123 static void rpcent_endstate(void *);
124 NSS_TLS_HANDLING(rpcent);
131 static int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
132 size_t, struct rpcent **);
133 static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
134 size_t, struct rpcent **);
135 static int wrap_getrpcent_r(union key, struct rpcent *, char *,
136 size_t, struct rpcent **);
137 static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
138 size_t, struct rpcent **), union key);
141 static int rpc_id_func(char *, size_t *, va_list, void *);
142 static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
143 static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
147 rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
148 size_t aliases_size, int *errnop)
156 cp = strpbrk(p, "#\n");
160 cp = strpbrk(p, " \t");
164 /* THIS STUFF IS INTERNET SPECIFIC */
166 while (*cp == ' ' || *cp == '\t')
168 rpc->r_number = atoi(cp);
169 q = rpc->r_aliases = r_aliases;
170 cp = strpbrk(cp, " \t");
174 if (*cp == ' ' || *cp == '\t') {
178 if (q < &(r_aliases[aliases_size - 1]))
185 cp = strpbrk(cp, " \t");
193 /* files backend implementation */
195 files_endstate(void *p)
202 f = ((struct files_state *)p)->fp;
210 files_rpcent(void *retval, void *mdata, va_list ap)
225 struct files_state *st;
228 enum nss_lookup_type how;
230 how = (enum nss_lookup_type)mdata;
234 name = va_arg(ap, char *);
237 number = va_arg(ap, int);
242 return (NS_NOTFOUND);
245 rpc = va_arg(ap, struct rpcent *);
246 buffer = va_arg(ap, char *);
247 bufsize = va_arg(ap, size_t);
248 errnop = va_arg(ap, int *);
250 *errnop = files_getstate(&st);
254 if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
259 if (how == nss_lt_all)
263 stayopen = st->stayopen;
267 if ((line = fgetln(st->fp, &linesize)) == NULL) {
273 if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
279 aliases = (char **)_ALIGN(&buffer[linesize+1]);
280 aliases_size = (buffer + bufsize -
281 (char *)aliases)/sizeof(char *);
282 if (aliases_size < 1) {
288 memcpy(buffer, line, linesize);
289 buffer[linesize] = '\0';
291 rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
306 if (strcmp(rpc->r_name, name) == 0)
308 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
309 if (strcmp(*rp, name) == 0)
318 rv = (rpc->r_number == number) ? NS_SUCCESS :
326 } while (!(rv & NS_TERMINATE));
328 if (!stayopen && st->fp!=NULL) {
333 if ((rv == NS_SUCCESS) && (retval != NULL))
334 *((struct rpcent **)retval) = rpc;
340 files_setrpcent(void *retval, void *mdata, va_list ap)
342 struct files_state *st;
346 rv = files_getstate(&st);
350 switch ((enum constants)mdata)
355 st->fp = fopen(RPCDB, "r");
361 if (st->fp != NULL) {
374 /* nis backend implementation */
377 nis_endstate(void *p)
382 free(((struct nis_state *)p)->current);
387 nis_rpcent(void *retval, void *mdata, va_list ap)
405 struct nis_state *st;
407 enum nss_lookup_type how;
410 how = (enum nss_lookup_type)mdata;
414 name = va_arg(ap, char *);
417 number = va_arg(ap, int);
422 return (NS_NOTFOUND);
426 rpc = va_arg(ap, struct rpcent *);
427 buffer = va_arg(ap, char *);
428 bufsize = va_arg(ap, size_t);
429 errnop = va_arg(ap, int *);
431 *errnop = nis_getstate(&st);
435 if (st->domain[0] == '\0') {
436 if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
447 if (!st->no_name_map)
450 asprintf(&buf, "%s", name);
452 return (NS_TRYAGAIN);
453 rv = yp_match(st->domain, "rpc.byname", buf,
454 strlen(buf), &resultbuf, &resultbuflen);
481 asprintf(&buf, "%d", number);
483 return (NS_TRYAGAIN);
484 if (yp_match(st->domain, "rpc.bynumber", buf,
485 strlen(buf), &resultbuf, &resultbuflen)) {
492 rv = yp_first(st->domain, "rpc.bynumber",
494 &st->currentlen, &resultbuf,
502 lastkey = st->current;
503 rv = yp_next(st->domain, "rpc.bynumber",
505 st->currentlen, &st->current,
507 &resultbuf, &resultbuflen);
518 /* we need a room for additional \n symbol */
519 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
527 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
528 aliases_size = (buffer + bufsize - (char *)aliases) /
530 if (aliases_size < 1) {
538 * rpcent_unpack expects lines terminated with \n -- make it happy
540 memcpy(buffer, resultbuf, resultbuflen);
541 buffer[resultbuflen] = '\n';
542 buffer[resultbuflen+1] = '\0';
545 if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
552 if ((how == nss_lt_all) && (no_name_active != 0)) {
553 if (strcmp(rpc->r_name, name) == 0)
555 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
556 if (strcmp(*rp, name) == 0)
567 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
571 if ((rv == NS_SUCCESS) && (retval != NULL))
572 *((struct rpcent **)retval) = rpc;
578 nis_setrpcent(void *retval, void *mdata, va_list ap)
580 struct nis_state *st;
583 rv = nis_getstate(&st);
587 switch ((enum constants)mdata)
605 rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
610 size_t desired_size, size;
611 enum nss_lookup_type lookup_type;
612 int res = NS_UNAVAIL;
614 lookup_type = (enum nss_lookup_type)cache_mdata;
615 switch (lookup_type) {
617 name = va_arg(ap, char *);
620 desired_size = sizeof(enum nss_lookup_type) + size + 1;
621 if (desired_size > *buffer_size) {
626 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
627 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
632 rpc = va_arg(ap, int);
634 desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
635 if (desired_size > *buffer_size) {
640 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
641 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc,
647 /* should be unreachable */
652 *buffer_size = desired_size;
657 rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
664 size_t orig_buf_size;
666 struct rpcent new_rpc;
667 size_t desired_size, size, aliases_size;
671 switch ((enum nss_lookup_type)cache_mdata) {
673 name = va_arg(ap, char *);
676 num = va_arg(ap, int);
681 /* should be unreachable */
685 rpc = va_arg(ap, struct rpcent *);
686 orig_buf = va_arg(ap, char *);
687 orig_buf_size = va_arg(ap, size_t);
689 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *);
690 if (rpc->r_name != NULL)
691 desired_size += strlen(rpc->r_name) + 1;
693 if (rpc->r_aliases != NULL) {
695 for (alias = rpc->r_aliases; *alias; ++alias) {
696 desired_size += strlen(*alias) + 1;
700 desired_size += _ALIGNBYTES + (aliases_size + 1) *
704 if (*buffer_size < desired_size) {
705 /* this assignment is here for future use */
706 *buffer_size = desired_size;
712 *buffer_size = desired_size;
713 memset(buffer, 0, desired_size);
714 p = buffer + sizeof(struct rpcent) + sizeof(char *);
715 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *));
716 p = (char *)_ALIGN(p);
718 if (new_rpc.r_name != NULL) {
719 size = strlen(new_rpc.r_name);
720 memcpy(p, new_rpc.r_name, size);
725 if (new_rpc.r_aliases != NULL) {
726 p = (char *)_ALIGN(p);
727 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size);
728 new_rpc.r_aliases = (char **)p;
729 p += sizeof(char *) * (aliases_size + 1);
731 for (alias = new_rpc.r_aliases; *alias; ++alias) {
732 size = strlen(*alias);
733 memcpy(p, *alias, size);
739 memcpy(buffer, &new_rpc, sizeof(struct rpcent));
744 rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
751 size_t orig_buf_size;
757 switch ((enum nss_lookup_type)cache_mdata) {
759 name = va_arg(ap, char *);
762 num = va_arg(ap, int);
767 /* should be unreachable */
771 rpc = va_arg(ap, struct rpcent *);
772 orig_buf = va_arg(ap, char *);
773 orig_buf_size = va_arg(ap, size_t);
774 ret_errno = va_arg(ap, int *);
777 buffer_size - sizeof(struct rpcent) - sizeof(char *)) {
782 memcpy(rpc, buffer, sizeof(struct rpcent));
783 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *));
785 orig_buf = (char *)_ALIGN(orig_buf);
786 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) +
787 _ALIGN(p) - (size_t)p,
788 buffer_size - sizeof(struct rpcent) - sizeof(char *) -
789 _ALIGN(p) + (size_t)p);
790 p = (char *)_ALIGN(p);
792 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *);
793 if (rpc->r_aliases != NULL) {
794 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **);
796 for (alias = rpc->r_aliases ; *alias; ++alias)
797 NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
801 *((struct rpcent **)retval) = rpc;
806 NSS_MP_CACHE_HANDLING(rpc);
807 #endif /* NS_CACHING */
810 /* get**_r functions implementation */
812 getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
813 size_t bufsize, struct rpcent **result)
816 static const nss_cache_info cache_info =
817 NS_COMMON_CACHE_INFO_INITIALIZER(
818 rpc, (void *)nss_lt_name,
819 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
821 static const ns_dtab dtab[] = {
822 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
824 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
827 NS_CACHE_CB(&cache_info)
835 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
836 name, rpc, buffer, bufsize, &ret_errno);
838 if (rv == NS_SUCCESS)
845 getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
846 size_t bufsize, struct rpcent **result)
849 static const nss_cache_info cache_info =
850 NS_COMMON_CACHE_INFO_INITIALIZER(
851 rpc, (void *)nss_lt_id,
852 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
854 static const ns_dtab dtab[] = {
855 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
857 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
860 NS_CACHE_CB(&cache_info)
868 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
869 number, rpc, buffer, bufsize, &ret_errno);
871 if (rv == NS_SUCCESS)
878 getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
879 struct rpcent **result)
882 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
883 rpc, (void *)nss_lt_all,
884 rpc_marshal_func, rpc_unmarshal_func);
886 static const ns_dtab dtab[] = {
887 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
889 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
892 NS_CACHE_CB(&cache_info)
900 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
901 rpc, buffer, bufsize, &ret_errno);
903 if (rv == NS_SUCCESS)
909 /* get** wrappers for get**_r functions implementation */
911 rpcent_endstate(void *p)
916 free(((struct rpcent_state *)p)->buffer);
921 wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer,
922 size_t bufsize, struct rpcent **res)
924 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
928 wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer,
929 size_t bufsize, struct rpcent **res)
931 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
935 wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer,
936 size_t bufsize, struct rpcent **res)
938 return (getrpcent_r(rpc, buffer, bufsize, res));
941 static struct rpcent *
942 getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
947 struct rpcent_state * st;
949 rv=rpcent_getstate(&st);
955 if (st->buffer == NULL) {
956 st->buffer = malloc(RPCENT_STORAGE_INITIAL);
957 if (st->buffer == NULL)
959 st->bufsize = RPCENT_STORAGE_INITIAL;
962 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
963 if (res == NULL && rv == ERANGE) {
965 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
971 st->buffer = malloc(st->bufsize);
972 if (st->buffer == NULL)
975 } while (res == NULL && rv == ERANGE);
983 getrpcbyname(const char *name)
989 return (getrpc(wrap_getrpcbyname_r, key));
993 getrpcbynumber(int number)
999 return (getrpc(wrap_getrpcbynumber_r, key));
1007 key.number = 0; /* not used */
1009 return (getrpc(wrap_getrpcent_r, key));
1013 setrpcent(int stayopen)
1016 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1017 rpc, (void *)nss_lt_all,
1021 static const ns_dtab dtab[] = {
1022 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
1024 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
1027 NS_CACHE_CB(&cache_info)
1029 { NULL, NULL, NULL }
1032 (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc,
1040 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1041 rpc, (void *)nss_lt_all,
1045 static const ns_dtab dtab[] = {
1046 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
1048 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
1051 NS_CACHE_CB(&cache_info)
1053 { NULL, NULL, NULL }
1056 (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc);