1 | /* |
2 | * Copyright (c) 2010, Oracle America, Inc. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions are |
6 | * met: |
7 | * |
8 | * * Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * * Redistributions in binary form must reproduce the above |
11 | * copyright notice, this list of conditions and the following |
12 | * disclaimer in the documentation and/or other materials |
13 | * provided with the distribution. |
14 | * * Neither the name of the "Oracle America, 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. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
25 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include <rpcsvc/yp.h> |
33 | #include <rpcsvc/ypclnt.h> |
34 | |
35 | /* The NIS v2 protocol suggests 1024 bytes as a maximum length of all fields. |
36 | Current Linux systems don't use this limit. To remain compatible with |
37 | recent Linux systems we choose limits large enough to load large key and |
38 | data values, but small enough to not pose a DoS threat. */ |
39 | |
40 | #define XDRMAXNAME 1024 |
41 | #define XDRMAXRECORD (16 * 1024 * 1024) |
42 | |
43 | bool_t |
44 | xdr_ypstat (XDR *xdrs, ypstat *objp) |
45 | { |
46 | return xdr_enum (xdrs, (enum_t *) objp); |
47 | } |
48 | libnsl_hidden_def (xdr_ypstat) |
49 | |
50 | bool_t |
51 | xdr_ypxfrstat (XDR *xdrs, ypxfrstat *objp) |
52 | { |
53 | return xdr_enum (xdrs, (enum_t *) objp); |
54 | } |
55 | libnsl_hidden_def (xdr_ypxfrstat) |
56 | |
57 | bool_t |
58 | xdr_domainname (XDR *xdrs, domainname *objp) |
59 | { |
60 | return xdr_string (xdrs, objp, XDRMAXNAME); |
61 | } |
62 | libnsl_hidden_def (xdr_domainname) |
63 | |
64 | bool_t |
65 | xdr_mapname (XDR *xdrs, mapname *objp) |
66 | { |
67 | return xdr_string (xdrs, objp, XDRMAXNAME); |
68 | } |
69 | libnsl_hidden_def (xdr_mapname) |
70 | |
71 | bool_t |
72 | xdr_peername (XDR *xdrs, peername *objp) |
73 | { |
74 | return xdr_string (xdrs, objp, XDRMAXNAME); |
75 | } |
76 | libnsl_hidden_def (xdr_peername) |
77 | |
78 | bool_t |
79 | xdr_keydat (XDR *xdrs, keydat *objp) |
80 | { |
81 | return xdr_bytes (xdrs, (char **) &objp->keydat_val, |
82 | (u_int *) &objp->keydat_len, XDRMAXRECORD); |
83 | } |
84 | libnsl_hidden_def (xdr_keydat) |
85 | |
86 | bool_t |
87 | xdr_valdat (XDR *xdrs, valdat *objp) |
88 | { |
89 | return xdr_bytes (xdrs, (char **) &objp->valdat_val, |
90 | (u_int *) &objp->valdat_len, XDRMAXRECORD); |
91 | } |
92 | libnsl_hidden_def (xdr_valdat) |
93 | |
94 | bool_t |
95 | xdr_ypmap_parms (XDR *xdrs, ypmap_parms *objp) |
96 | { |
97 | if (!xdr_domainname (xdrs, &objp->domain)) |
98 | return FALSE; |
99 | if (!xdr_mapname (xdrs, &objp->map)) |
100 | return FALSE; |
101 | if (!xdr_u_int (xdrs, &objp->ordernum)) |
102 | return FALSE; |
103 | return xdr_peername (xdrs, &objp->peer); |
104 | } |
105 | libnsl_hidden_def (xdr_ypmap_parms) |
106 | |
107 | bool_t |
108 | xdr_ypreq_key (XDR *xdrs, ypreq_key *objp) |
109 | { |
110 | if (!xdr_domainname (xdrs, &objp->domain)) |
111 | return FALSE; |
112 | if (!xdr_mapname (xdrs, &objp->map)) |
113 | return FALSE; |
114 | return xdr_keydat (xdrs, &objp->key); |
115 | } |
116 | libnsl_hidden_def (xdr_ypreq_key) |
117 | |
118 | bool_t |
119 | xdr_ypreq_nokey (XDR *xdrs, ypreq_nokey *objp) |
120 | { |
121 | if (!xdr_domainname (xdrs, &objp->domain)) |
122 | return FALSE; |
123 | return xdr_mapname (xdrs, &objp->map); |
124 | } |
125 | libnsl_hidden_def (xdr_ypreq_nokey) |
126 | |
127 | bool_t |
128 | xdr_ypreq_xfr (XDR *xdrs, ypreq_xfr *objp) |
129 | { |
130 | if (!xdr_ypmap_parms (xdrs, &objp->map_parms)) |
131 | return FALSE; |
132 | if (!xdr_u_int (xdrs, &objp->transid)) |
133 | return FALSE; |
134 | if (!xdr_u_int (xdrs, &objp->prog)) |
135 | return FALSE; |
136 | return xdr_u_int (xdrs, &objp->port); |
137 | } |
138 | |
139 | bool_t |
140 | xdr_ypresp_val (XDR *xdrs, ypresp_val *objp) |
141 | { |
142 | if (!xdr_ypstat (xdrs, &objp->stat)) |
143 | return FALSE; |
144 | return xdr_valdat (xdrs, &objp->val); |
145 | } |
146 | libnsl_hidden_def (xdr_ypresp_val) |
147 | |
148 | bool_t |
149 | xdr_ypresp_key_val (XDR *xdrs, ypresp_key_val *objp) |
150 | { |
151 | if (!xdr_ypstat (xdrs, &objp->stat)) |
152 | return FALSE; |
153 | if (!xdr_valdat (xdrs, &objp->val)) |
154 | return FALSE; |
155 | return xdr_keydat (xdrs, &objp->key); |
156 | } |
157 | libnsl_hidden_def (xdr_ypresp_key_val) |
158 | |
159 | bool_t |
160 | xdr_ypresp_master (XDR *xdrs, ypresp_master *objp) |
161 | { |
162 | if (!xdr_ypstat (xdrs, &objp->stat)) |
163 | return FALSE; |
164 | return xdr_peername (xdrs, &objp->peer); |
165 | } |
166 | libnsl_hidden_def (xdr_ypresp_master) |
167 | |
168 | bool_t |
169 | xdr_ypresp_order (XDR *xdrs, ypresp_order *objp) |
170 | { |
171 | if (!xdr_ypstat (xdrs, &objp->stat)) |
172 | return FALSE; |
173 | return xdr_u_int (xdrs, &objp->ordernum); |
174 | } |
175 | libnsl_hidden_def (xdr_ypresp_order) |
176 | |
177 | bool_t |
178 | xdr_ypresp_all (XDR *xdrs, ypresp_all *objp) |
179 | { |
180 | if (!xdr_bool (xdrs, &objp->more)) |
181 | return FALSE; |
182 | switch (objp->more) |
183 | { |
184 | case TRUE: |
185 | return xdr_ypresp_key_val (xdrs, &objp->ypresp_all_u.val); |
186 | case FALSE: |
187 | break; |
188 | default: |
189 | return FALSE; |
190 | } |
191 | return TRUE; |
192 | } |
193 | libnsl_hidden_def (xdr_ypresp_all) |
194 | |
195 | bool_t |
196 | xdr_ypresp_xfr (XDR *xdrs, ypresp_xfr *objp) |
197 | { |
198 | if (!xdr_u_int (xdrs, &objp->transid)) |
199 | return FALSE; |
200 | return xdr_ypxfrstat (xdrs, &objp->xfrstat); |
201 | } |
202 | |
203 | bool_t |
204 | xdr_ypmaplist (XDR *xdrs, ypmaplist *objp) |
205 | { |
206 | if (!xdr_mapname (xdrs, &objp->map)) |
207 | return FALSE; |
208 | /* Prevent gcc warning about alias violation. */ |
209 | char **tp = (void *) &objp->next; |
210 | return xdr_pointer (xdrs, tp, sizeof (ypmaplist), (xdrproc_t) xdr_ypmaplist); |
211 | } |
212 | libnsl_hidden_def (xdr_ypmaplist) |
213 | |
214 | bool_t |
215 | xdr_ypresp_maplist (XDR *xdrs, ypresp_maplist *objp) |
216 | { |
217 | if (!xdr_ypstat (xdrs, &objp->stat)) |
218 | return FALSE; |
219 | /* Prevent gcc warning about alias violation. */ |
220 | char **tp = (void *) &objp->maps; |
221 | return xdr_pointer (xdrs, tp, sizeof (ypmaplist), (xdrproc_t) xdr_ypmaplist); |
222 | } |
223 | libnsl_hidden_def (xdr_ypresp_maplist) |
224 | |
225 | bool_t |
226 | xdr_yppush_status (XDR *xdrs, yppush_status *objp) |
227 | { |
228 | return xdr_enum (xdrs, (enum_t *) objp); |
229 | } |
230 | libnsl_hidden_def (xdr_yppush_status) |
231 | |
232 | bool_t |
233 | xdr_yppushresp_xfr (XDR *xdrs, yppushresp_xfr *objp) |
234 | { |
235 | if (!xdr_u_int (xdrs, &objp->transid)) |
236 | return FALSE; |
237 | return xdr_yppush_status (xdrs, &objp->status); |
238 | } |
239 | |
240 | bool_t |
241 | xdr_ypbind_resptype (XDR *xdrs, ypbind_resptype *objp) |
242 | { |
243 | return xdr_enum (xdrs, (enum_t *) objp); |
244 | } |
245 | libnsl_hidden_def (xdr_ypbind_resptype) |
246 | |
247 | bool_t |
248 | xdr_ypbind_binding (XDR *xdrs, ypbind_binding *objp) |
249 | { |
250 | if (!xdr_opaque (xdrs, objp->ypbind_binding_addr, 4)) |
251 | return FALSE; |
252 | return xdr_opaque (xdrs, objp->ypbind_binding_port, 2); |
253 | } |
254 | libnsl_hidden_def (xdr_ypbind_binding) |
255 | |
256 | bool_t |
257 | xdr_ypbind_resp (XDR *xdrs, ypbind_resp *objp) |
258 | { |
259 | if (!xdr_ypbind_resptype (xdrs, &objp->ypbind_status)) |
260 | return FALSE; |
261 | switch (objp->ypbind_status) |
262 | { |
263 | case YPBIND_FAIL_VAL: |
264 | return xdr_u_int (xdrs, &objp->ypbind_resp_u.ypbind_error); |
265 | case YPBIND_SUCC_VAL: |
266 | return xdr_ypbind_binding (xdrs, &objp->ypbind_resp_u.ypbind_bindinfo); |
267 | } |
268 | return FALSE; |
269 | } |
270 | libnsl_hidden_def (xdr_ypbind_resp) |
271 | |
272 | bool_t |
273 | xdr_ypbind_setdom (XDR *xdrs, ypbind_setdom *objp) |
274 | { |
275 | if (!xdr_domainname (xdrs, &objp->ypsetdom_domain)) |
276 | return FALSE; |
277 | if (!xdr_ypbind_binding (xdrs, &objp->ypsetdom_binding)) |
278 | return FALSE; |
279 | return xdr_u_int (xdrs, &objp->ypsetdom_vers); |
280 | } |
281 | |
282 | bool_t |
283 | xdr_ypall(XDR *xdrs, struct ypall_callback *incallback) |
284 | { |
285 | struct ypresp_key_val out; |
286 | char key[YPMAXRECORD], val[YPMAXRECORD]; |
287 | |
288 | /* |
289 | * Set up key/val struct to be used during the transaction. |
290 | */ |
291 | memset(&out, 0, sizeof out); |
292 | out.key.keydat_val = key; |
293 | out.key.keydat_len = sizeof(key); |
294 | out.val.valdat_val = val; |
295 | out.val.valdat_len = sizeof(val); |
296 | |
297 | for (;;) { |
298 | bool_t more, status; |
299 | |
300 | /* Values pending? */ |
301 | if (!xdr_bool(xdrs, &more)) |
302 | return FALSE; /* can't tell! */ |
303 | if (!more) |
304 | return TRUE; /* no more */ |
305 | |
306 | /* Transfer key/value pair. */ |
307 | status = xdr_ypresp_key_val(xdrs, &out); |
308 | |
309 | /* |
310 | * If we succeeded, call the callback function. |
311 | * The callback will return TRUE when it wants |
312 | * no more values. If we fail, indicate the |
313 | * error. |
314 | */ |
315 | if (status) { |
316 | if ((*incallback->foreach)(out.stat, |
317 | (char *)out.key.keydat_val, out.key.keydat_len, |
318 | (char *)out.val.valdat_val, out.val.valdat_len, |
319 | incallback->data)) |
320 | return TRUE; |
321 | } else |
322 | return FALSE; |
323 | } |
324 | } |
325 | |