xref: /netbsd-src/lib/libc/yp/yp_first.c (revision 4be2f99d7b796075be09b940699672ca22c01984)
1 /*	$NetBSD: yp_first.c,v 1.17 2024/01/03 18:41:53 christos Exp $	 */
2 
3 /*
4  * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 #if defined(LIBC_SCCS) && !defined(lint)
31 __RCSID("$NetBSD: yp_first.c,v 1.17 2024/01/03 18:41:53 christos Exp $");
32 #endif
33 
34 #include "namespace.h"
35 #include <stdlib.h>
36 #include <string.h>
37 #include <rpc/rpc.h>
38 #include <rpcsvc/yp_prot.h>
39 #include <rpcsvc/ypclnt.h>
40 #include "local.h"
41 
42 #ifdef __weak_alias
__weak_alias(yp_first,_yp_first)43 __weak_alias(yp_first,_yp_first)
44 __weak_alias(yp_next,_yp_next)
45 #endif
46 
47 int
48 yp_first(const char *indomain, const char *inmap, char **outkey,
49     int *outkeylen, char **outval, int *outvallen)
50 {
51 	struct ypresp_key_val yprkv;
52 	struct ypreq_nokey yprnk;
53 	struct dom_binding *ysd;
54 	int r, nerrs = 0;
55 
56 	if (outkey == NULL || outkeylen == NULL || \
57 	    outval == NULL || outvallen == NULL)
58 		return YPERR_BADARGS;
59 	*outkey = *outval = NULL;
60 	*outkeylen = *outvallen = 0;
61 	if (_yp_invalid_domain(indomain))
62 		return YPERR_BADARGS;
63 	if (inmap == NULL || *inmap == '\0'
64 	    || strlen(inmap) > YPMAXMAP)
65 		return YPERR_BADARGS;
66 
67 again:
68 	if (_yp_dobind(indomain, &ysd) != 0)
69 		return YPERR_DOMAIN;
70 
71 	yprnk.domain = indomain;
72 	yprnk.map = inmap;
73 	(void)memset(&yprkv, 0, sizeof yprkv);
74 
75 	r = clnt_call(ysd->dom_client, (rpcproc_t)YPPROC_FIRST,
76 	    (xdrproc_t)xdr_ypreq_nokey,
77 	    &yprnk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, _yplib_timeout);
78 	if (r != RPC_SUCCESS) {
79 		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
80 			clnt_perror(ysd->dom_client, "yp_first: clnt_call");
81 			nerrs = 0;
82 		} else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries)
83 			return YPERR_YPSERV;
84 		ysd->dom_vers = -1;
85 		goto again;
86 	}
87 	if (!(r = ypprot_err(yprkv.status))) {
88 		*outkeylen = yprkv.keydat.dsize;
89 		if ((*outkey = malloc((size_t)(*outkeylen + 1))) == NULL)
90 			r = YPERR_RESRC;
91 		else {
92 			(void)memcpy(*outkey, yprkv.keydat.dptr,
93 			    (size_t)*outkeylen);
94 			(*outkey)[*outkeylen] = '\0';
95 		}
96 		*outvallen = yprkv.valdat.dsize;
97 		if ((*outval = malloc((size_t)(*outvallen + 1))) == NULL)
98 			r = YPERR_RESRC;
99 		else {
100 			(void)memcpy(*outval, yprkv.valdat.dptr,
101 			    (size_t)*outvallen);
102 			(*outval)[*outvallen] = '\0';
103 		}
104 	}
105 	xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)(void *)&yprkv);
106 	__yp_unbind(ysd);
107 	if (r != 0) {
108 		if (*outkey) {
109 			free(*outkey);
110 			*outkey = NULL;
111 		}
112 		if (*outval) {
113 			free(*outval);
114 			*outval = NULL;
115 		}
116 	}
117 	return r;
118 }
119 
120 int
yp_next(const char * indomain,const char * inmap,const char * inkey,int inkeylen,char ** outkey,int * outkeylen,char ** outval,int * outvallen)121 yp_next(const char *indomain, const char *inmap, const char *inkey,
122     int inkeylen, char **outkey, int *outkeylen, char **outval, int *outvallen)
123 {
124 	struct ypresp_key_val yprkv;
125 	struct ypreq_key yprk;
126 	struct dom_binding *ysd;
127 	int r, nerrs = 0;
128 
129 	if (outkey == NULL || outkeylen == NULL || \
130 	    outval == NULL || outvallen == NULL || \
131 	    inkey == NULL)
132 		return YPERR_BADARGS;
133 	*outkey = *outval = NULL;
134 	*outkeylen = *outvallen = 0;
135 
136 	if (_yp_invalid_domain(indomain))
137 		return YPERR_BADARGS;
138 	if (inmap == NULL || *inmap == '\0'
139 	    || strlen(inmap) > YPMAXMAP)
140 		return YPERR_BADARGS;
141 
142 again:
143 	if (_yp_dobind(indomain, &ysd) != 0)
144 		return YPERR_DOMAIN;
145 
146 	yprk.domain = indomain;
147 	yprk.map = inmap;
148 	yprk.keydat.dptr = inkey;
149 	yprk.keydat.dsize = inkeylen;
150 	(void)memset(&yprkv, 0, sizeof yprkv);
151 
152 	r = clnt_call(ysd->dom_client, (rpcproc_t)YPPROC_NEXT,
153 	    (xdrproc_t)xdr_ypreq_key,
154 	    &yprk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, _yplib_timeout);
155 	if (r != RPC_SUCCESS) {
156 		if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) {
157 			clnt_perror(ysd->dom_client, "yp_next: clnt_call");
158 			nerrs = 0;
159 		} else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries)
160 			return YPERR_YPSERV;
161 		ysd->dom_vers = -1;
162 		goto again;
163 	}
164 	if (!(r = ypprot_err(yprkv.status))) {
165 		*outkeylen = yprkv.keydat.dsize;
166 		if ((*outkey = malloc((size_t)(*outkeylen + 1))) == NULL)
167 			r = YPERR_RESRC;
168 		else {
169 			(void)memcpy(*outkey, yprkv.keydat.dptr,
170 			    (size_t)*outkeylen);
171 			(*outkey)[*outkeylen] = '\0';
172 		}
173 		*outvallen = yprkv.valdat.dsize;
174 		if ((*outval = malloc((size_t)(*outvallen + 1))) == NULL)
175 			r = YPERR_RESRC;
176 		else {
177 			(void)memcpy(*outval, yprkv.valdat.dptr,
178 			    (size_t)*outvallen);
179 			(*outval)[*outvallen] = '\0';
180 		}
181 	}
182 	xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)(void *)&yprkv);
183 	__yp_unbind(ysd);
184 	if (r != 0) {
185 		if (*outkey) {
186 			free(*outkey);
187 			*outkey = NULL;
188 		}
189 		if (*outval) {
190 			free(*outval);
191 			*outval = NULL;
192 		}
193 	}
194 	return r;
195 }
196