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