1 /* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user or with the express written consent of
10 * Sun Microsystems, Inc.
12 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
13 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
14 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
16 * Sun RPC is provided with no support and without any obligation on the
17 * part of Sun Microsystems, Inc. to assist in its use, correction,
18 * modification or enhancement.
20 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
21 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
22 * OR ANY PART THEREOF.
24 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
25 * or profits or other special, indirect and consequential damages, even if
26 * Sun has been advised of the possibility of such damages.
28 * Sun Microsystems, Inc.
30 * Mountain View, California 94043
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/types.h>
45 #include <sys/socket.h>
46 #include <arpa/inet.h>
50 #include <netinet/in.h>
57 #include <rpcsvc/yp_prot.h>
58 #include <rpcsvc/ypclnt.h>
61 #include "namespace.h"
62 #include "reentrant.h"
63 #include "un-namespace.h"
64 #include "libc_private.h"
70 #define RPCDB "/etc/rpc"
72 /* nsswitch declarations */
77 RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
78 RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */
81 static const ns_src defaultsrc[] = {
82 { NSSRC_FILES, NS_SUCCESS },
84 { NSSRC_NIS, NS_SUCCESS },
89 /* files backend declarations */
95 static int files_rpcent(void *, void *, va_list);
96 static int files_setrpcent(void *, void *, va_list);
98 static void files_endstate(void *);
99 NSS_TLS_HANDLING(files);
101 /* nis backend declarations */
104 char domain[MAXHOSTNAMELEN];
111 static int nis_rpcent(void *, void *, va_list);
112 static int nis_setrpcent(void *, void *, va_list);
114 static void nis_endstate(void *);
115 NSS_TLS_HANDLING(nis);
118 /* get** wrappers for get**_r functions declarations */
119 struct rpcent_state {
124 static void rpcent_endstate(void *);
125 NSS_TLS_HANDLING(rpcent);
132 static int wrap_getrpcbyname_r(union key, struct rpcent *, char *,
133 size_t, struct rpcent **);
134 static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *,
135 size_t, struct rpcent **);
136 static int wrap_getrpcent_r(union key, struct rpcent *, char *,
137 size_t, struct rpcent **);
138 static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *,
139 size_t, struct rpcent **), union key);
142 static int rpc_id_func(char *, size_t *, va_list, void *);
143 static int rpc_marshal_func(char *, size_t *, void *, va_list, void *);
144 static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *);
148 rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases,
149 size_t aliases_size, int *errnop)
157 cp = strpbrk(p, "#\n");
161 cp = strpbrk(p, " \t");
165 /* THIS STUFF IS INTERNET SPECIFIC */
167 while (*cp == ' ' || *cp == '\t')
169 rpc->r_number = atoi(cp);
170 q = rpc->r_aliases = r_aliases;
171 cp = strpbrk(cp, " \t");
175 if (*cp == ' ' || *cp == '\t') {
179 if (q < &(r_aliases[aliases_size - 1]))
186 cp = strpbrk(cp, " \t");
194 /* files backend implementation */
196 files_endstate(void *p)
203 f = ((struct files_state *)p)->fp;
211 files_rpcent(void *retval, void *mdata, va_list ap)
226 struct files_state *st;
229 enum nss_lookup_type how;
231 how = (enum nss_lookup_type)mdata;
235 name = va_arg(ap, char *);
238 number = va_arg(ap, int);
243 return (NS_NOTFOUND);
246 rpc = va_arg(ap, struct rpcent *);
247 buffer = va_arg(ap, char *);
248 bufsize = va_arg(ap, size_t);
249 errnop = va_arg(ap, int *);
251 *errnop = files_getstate(&st);
255 if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) {
260 if (how == nss_lt_all)
264 stayopen = st->stayopen;
268 if ((line = fgetln(st->fp, &linesize)) == NULL) {
274 if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
280 aliases = (char **)_ALIGN(&buffer[linesize+1]);
281 aliases_size = (buffer + bufsize -
282 (char *)aliases)/sizeof(char *);
283 if (aliases_size < 1) {
289 memcpy(buffer, line, linesize);
290 buffer[linesize] = '\0';
292 rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop);
307 if (strcmp(rpc->r_name, name) == 0)
309 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
310 if (strcmp(*rp, name) == 0)
319 rv = (rpc->r_number == number) ? NS_SUCCESS :
327 } while (!(rv & NS_TERMINATE));
329 if (!stayopen && st->fp!=NULL) {
334 if ((rv == NS_SUCCESS) && (retval != NULL))
335 *((struct rpcent **)retval) = rpc;
341 files_setrpcent(void *retval, void *mdata, va_list ap)
343 struct files_state *st;
347 rv = files_getstate(&st);
351 switch ((enum constants)mdata)
356 st->fp = fopen(RPCDB, "r");
362 if (st->fp != NULL) {
375 /* nis backend implementation */
378 nis_endstate(void *p)
383 free(((struct nis_state *)p)->current);
388 nis_rpcent(void *retval, void *mdata, va_list ap)
404 char buf[YPMAXRECORD + 2];
406 struct nis_state *st;
408 enum nss_lookup_type how;
411 how = (enum nss_lookup_type)mdata;
415 name = va_arg(ap, char *);
418 number = va_arg(ap, int);
423 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)
449 snprintf(buf, sizeof buf, "%s", name);
450 rv = yp_match(st->domain, "rpc.byname", buf,
451 strlen(buf), &resultbuf, &resultbuflen);
477 snprintf(buf, sizeof buf, "%d", number);
478 if (yp_match(st->domain, "rpc.bynumber", buf,
479 strlen(buf), &resultbuf, &resultbuflen)) {
486 rv = yp_first(st->domain, "rpc.bynumber",
488 &st->currentlen, &resultbuf,
496 lastkey = st->current;
497 rv = yp_next(st->domain, "rpc.bynumber",
499 st->currentlen, &st->current,
501 &resultbuf, &resultbuflen);
512 /* we need a room for additional \n symbol */
513 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
520 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
521 aliases_size = (buffer + bufsize - (char *)aliases) /
523 if (aliases_size < 1) {
530 * rpcent_unpack expects lines terminated with \n -- make it happy
532 memcpy(buffer, resultbuf, resultbuflen);
533 buffer[resultbuflen] = '\n';
534 buffer[resultbuflen+1] = '\0';
537 if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
544 if ((how == nss_lt_all) && (no_name_active != 0)) {
545 if (strcmp(rpc->r_name, name) == 0)
547 for (rp = rpc->r_aliases; *rp != NULL; rp++) {
548 if (strcmp(*rp, name) == 0)
559 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
562 if ((rv == NS_SUCCESS) && (retval != NULL))
563 *((struct rpcent **)retval) = rpc;
569 nis_setrpcent(void *retval, void *mdata, va_list ap)
571 struct nis_state *st;
574 rv = nis_getstate(&st);
578 switch ((enum constants)mdata)
596 rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
601 size_t desired_size, size;
602 enum nss_lookup_type lookup_type;
603 int res = NS_UNAVAIL;
605 lookup_type = (enum nss_lookup_type)cache_mdata;
606 switch (lookup_type) {
608 name = va_arg(ap, char *);
611 desired_size = sizeof(enum nss_lookup_type) + size + 1;
612 if (desired_size > *buffer_size) {
617 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
618 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
623 rpc = va_arg(ap, int);
625 desired_size = sizeof(enum nss_lookup_type) + sizeof(int);
626 if (desired_size > *buffer_size) {
631 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
632 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc,
638 /* should be unreachable */
643 *buffer_size = desired_size;
648 rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
655 size_t orig_buf_size;
657 struct rpcent new_rpc;
658 size_t desired_size, size, aliases_size;
662 switch ((enum nss_lookup_type)cache_mdata) {
664 name = va_arg(ap, char *);
667 num = va_arg(ap, int);
672 /* should be unreachable */
676 rpc = va_arg(ap, struct rpcent *);
677 orig_buf = va_arg(ap, char *);
678 orig_buf_size = va_arg(ap, size_t);
680 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *);
681 if (rpc->r_name != NULL)
682 desired_size += strlen(rpc->r_name) + 1;
684 if (rpc->r_aliases != NULL) {
686 for (alias = rpc->r_aliases; *alias; ++alias) {
687 desired_size += strlen(*alias) + 1;
691 desired_size += _ALIGNBYTES + (aliases_size + 1) *
695 if (*buffer_size < desired_size) {
696 /* this assignment is here for future use */
697 *buffer_size = desired_size;
701 memcpy(&new_rpc, rpc, sizeof(struct rpcent));
703 *buffer_size = desired_size;
704 memset(buffer, 0, desired_size);
705 p = buffer + sizeof(struct rpcent) + sizeof(char *);
706 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *));
707 p = (char *)_ALIGN(p);
709 if (new_rpc.r_name != NULL) {
710 size = strlen(new_rpc.r_name);
711 memcpy(p, new_rpc.r_name, size);
716 if (new_rpc.r_aliases != NULL) {
717 p = (char *)_ALIGN(p);
718 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size);
719 new_rpc.r_aliases = (char **)p;
720 p += sizeof(char *) * (aliases_size + 1);
722 for (alias = new_rpc.r_aliases; *alias; ++alias) {
723 size = strlen(*alias);
724 memcpy(p, *alias, size);
730 memcpy(buffer, &new_rpc, sizeof(struct rpcent));
735 rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
742 size_t orig_buf_size;
748 switch ((enum nss_lookup_type)cache_mdata) {
750 name = va_arg(ap, char *);
753 num = va_arg(ap, int);
758 /* should be unreachable */
762 rpc = va_arg(ap, struct rpcent *);
763 orig_buf = va_arg(ap, char *);
764 orig_buf_size = va_arg(ap, size_t);
765 ret_errno = va_arg(ap, int *);
768 buffer_size - sizeof(struct rpcent) - sizeof(char *)) {
773 memcpy(rpc, buffer, sizeof(struct rpcent));
774 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *));
776 orig_buf = (char *)_ALIGN(orig_buf);
777 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) +
778 _ALIGN(p) - (size_t)p,
779 buffer_size - sizeof(struct rpcent) - sizeof(char *) -
780 _ALIGN(p) + (size_t)p);
781 p = (char *)_ALIGN(p);
783 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *);
784 if (rpc->r_aliases != NULL) {
785 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **);
787 for (alias = rpc->r_aliases ; *alias; ++alias)
788 NS_APPLY_OFFSET(*alias, orig_buf, p, char *);
792 *((struct rpcent **)retval) = rpc;
797 NSS_MP_CACHE_HANDLING(rpc);
798 #endif /* NS_CACHING */
801 /* get**_r functions implementation */
803 getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer,
804 size_t bufsize, struct rpcent **result)
807 static const nss_cache_info cache_info =
808 NS_COMMON_CACHE_INFO_INITIALIZER(
809 rpc, (void *)nss_lt_name,
810 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
812 static const ns_dtab dtab[] = {
813 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name },
815 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name },
818 NS_CACHE_CB(&cache_info)
826 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc,
827 name, rpc, buffer, bufsize, &ret_errno);
829 if (rv == NS_SUCCESS)
836 getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer,
837 size_t bufsize, struct rpcent **result)
840 static const nss_cache_info cache_info =
841 NS_COMMON_CACHE_INFO_INITIALIZER(
842 rpc, (void *)nss_lt_id,
843 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func);
845 static const ns_dtab dtab[] = {
846 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id },
848 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id },
851 NS_CACHE_CB(&cache_info)
859 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc,
860 number, rpc, buffer, bufsize, &ret_errno);
862 if (rv == NS_SUCCESS)
869 getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize,
870 struct rpcent **result)
873 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
874 rpc, (void *)nss_lt_all,
875 rpc_marshal_func, rpc_unmarshal_func);
877 static const ns_dtab dtab[] = {
878 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all },
880 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all },
883 NS_CACHE_CB(&cache_info)
891 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc,
892 rpc, buffer, bufsize, &ret_errno);
894 if (rv == NS_SUCCESS)
900 /* get** wrappers for get**_r functions implementation */
902 rpcent_endstate(void *p)
907 free(((struct rpcent_state *)p)->buffer);
912 wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer,
913 size_t bufsize, struct rpcent **res)
915 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res));
919 wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer,
920 size_t bufsize, struct rpcent **res)
922 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res));
926 wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer,
927 size_t bufsize, struct rpcent **res)
929 return (getrpcent_r(rpc, buffer, bufsize, res));
932 static struct rpcent *
933 getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **),
938 struct rpcent_state * st;
940 rv=rpcent_getstate(&st);
946 if (st->buffer == NULL) {
947 st->buffer = malloc(RPCENT_STORAGE_INITIAL);
948 if (st->buffer == NULL)
950 st->bufsize = RPCENT_STORAGE_INITIAL;
953 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res);
954 if (res == NULL && rv == ERANGE) {
956 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) {
962 st->buffer = malloc(st->bufsize);
963 if (st->buffer == NULL)
966 } while (res == NULL && rv == ERANGE);
974 getrpcbyname(char *name)
980 return (getrpc(wrap_getrpcbyname_r, key));
984 getrpcbynumber(int number)
990 return (getrpc(wrap_getrpcbynumber_r, key));
998 key.number = 0; /* not used */
1000 return (getrpc(wrap_getrpcent_r, key));
1004 setrpcent(int stayopen)
1007 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1008 rpc, (void *)nss_lt_all,
1012 static const ns_dtab dtab[] = {
1013 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT },
1015 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT },
1018 NS_CACHE_CB(&cache_info)
1020 { NULL, NULL, NULL }
1023 (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc,
1031 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER(
1032 rpc, (void *)nss_lt_all,
1036 static const ns_dtab dtab[] = {
1037 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT },
1039 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT },
1042 NS_CACHE_CB(&cache_info)
1044 { NULL, NULL, NULL }
1047 (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc);