1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23/*
24 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25 * Use is subject to license terms.
26 */
27
28/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
29/*	  All Rights Reserved   */
30
31/*
32 * Portions of this source code were derived from Berkeley
33 * under license from the Regents of the University of
34 * California.
35 */
36
37#pragma ident	"%Z%%M%	%I%	%E% SMI"
38
39/*
40 * This contains ALL xdr routines used by the YP rpc interface.
41 */
42
43#include "mt.h"
44#include <unistd.h>
45#include <stdlib.h>
46#include <rpc/rpc.h>
47#include "yp_b.h"
48#include <rpcsvc/yp_prot.h>
49#include <rpcsvc/ypclnt.h>
50#include <sys/types.h>
51#include <limits.h>
52
53static bool xdr_ypmaplist(XDR *, struct ypmaplist **);
54static bool xdr_ypmaplist_wrap_string(XDR *, char *);
55
56typedef struct xdr_discrim XDR_DISCRIM;
57extern bool xdr_ypreq_key(XDR *, struct ypreq_key *);
58extern bool xdr_ypreq_nokey(XDR *, struct ypreq_nokey *);
59extern bool xdr_ypresp_val(XDR *, struct ypresp_val *);
60extern bool xdr_ypresp_key_val(XDR *, struct ypresp_key_val *);
61extern bool xdr_ypmap_parms(XDR *, struct ypmap_parms *);
62extern bool xdr_ypowner_wrap_string(XDR *, char **);
63extern bool xdr_ypreq_newname_string(XDR *, char **);
64
65
66/*
67 * Serializes/deserializes a dbm datum data structure.
68 */
69bool
70xdr_datum(XDR *xdrs, datum *pdatum)
71{
72	bool res;
73	uint_t dsize;
74
75	/*
76	 * LP64 case :
77	 * xdr_bytes() expects a uint_t for the 3rd argument. Since
78	 * datum.dsize is a long, we need a new temporary to pass to
79	 * xdr_bytes()
80	 */
81	if (xdrs->x_op == XDR_ENCODE) {
82		if (pdatum->dsize > UINT_MAX)
83			return (FALSE);
84	}
85	dsize = (uint_t)pdatum->dsize;
86	res = (bool)xdr_bytes(xdrs, (char **)&(pdatum->dptr), &dsize,
87								YPMAXRECORD);
88	if (xdrs->x_op == XDR_DECODE) {
89		pdatum->dsize = dsize;
90	}
91
92	return (res);
93}
94
95
96/*
97 * Serializes/deserializes a domain name string.  This is a "wrapper" for
98 * xdr_string which knows about the maximum domain name size.
99 */
100bool
101xdr_ypdomain_wrap_string(XDR *xdrs, char **ppstring)
102{
103	return ((bool)xdr_string(xdrs, ppstring, YPMAXDOMAIN));
104}
105
106/*
107 * Serializes/deserializes a map name string.  This is a "wrapper" for
108 * xdr_string which knows about the maximum map name size.
109 */
110bool
111xdr_ypmap_wrap_string(XDR *xdrs, char **ppstring)
112{
113	return ((bool)xdr_string(xdrs, ppstring, YPMAXMAP));
114}
115
116/*
117 * Serializes/deserializes a ypreq_key structure.
118 */
119bool
120xdr_ypreq_key(XDR *xdrs, struct ypreq_key *ps)
121{
122	return ((bool)(xdr_ypdomain_wrap_string(xdrs, &ps->domain) &&
123		    xdr_ypmap_wrap_string(xdrs, &ps->map) &&
124		    xdr_datum(xdrs, &ps->keydat)));
125}
126
127/*
128 * Serializes/deserializes a ypreq_nokey structure.
129 */
130bool
131xdr_ypreq_nokey(XDR *xdrs, struct ypreq_nokey *ps)
132{
133	return ((bool)(xdr_ypdomain_wrap_string(xdrs, &ps->domain) &&
134		    xdr_ypmap_wrap_string(xdrs, &ps->map)));
135}
136
137/*
138 * Serializes/deserializes a ypresp_val structure.
139 */
140bool
141xdr_ypresp_val(XDR *xdrs, struct ypresp_val *ps)
142{
143	return ((bool)(xdr_u_int(xdrs, &ps->status) &&
144		    xdr_datum(xdrs, &ps->valdat)));
145}
146
147/*
148 * Serializes/deserializes a ypresp_key_val structure.
149 */
150bool
151xdr_ypresp_key_val(XDR *xdrs, struct ypresp_key_val *ps)
152{
153	return ((bool)(xdr_u_int(xdrs, &ps->status) &&
154	    xdr_datum(xdrs, &ps->valdat) &&
155	    xdr_datum(xdrs, &ps->keydat)));
156}
157
158/*
159 * Serializes/deserializes a peer server's node name
160 */
161bool
162xdr_ypowner_wrap_string(XDR *xdrs, char **ppstring)
163{
164	return ((bool)xdr_string(xdrs, ppstring, YPMAXPEER));
165}
166
167/*
168 * Serializes/deserializes a ypmap_parms structure.
169 */
170bool
171xdr_ypmap_parms(XDR *xdrs, struct ypmap_parms *ps)
172{
173	return ((bool)(xdr_ypdomain_wrap_string(xdrs, &ps->domain) &&
174	    xdr_ypmap_wrap_string(xdrs, &ps->map) &&
175	    xdr_u_int(xdrs, &ps->ordernum) &&
176	    xdr_ypowner_wrap_string(xdrs, &ps->owner)));
177}
178
179/*
180 * Serializes/deserializes a ypreq_newxfr name
181 */
182bool
183xdr_ypreq_newname_string(XDR *xdrs, char **ppstring)
184{
185	return ((bool)xdr_string(xdrs, ppstring, 256));
186}
187
188/*
189 * Serializes/deserializes a ypresp_master structure.
190 */
191bool
192xdr_ypresp_master(XDR *xdrs, struct ypresp_master *ps)
193{
194	return ((bool)(xdr_u_int(xdrs, &ps->status) &&
195	    xdr_ypowner_wrap_string(xdrs, &ps->master)));
196}
197
198/*
199 * Serializes/deserializes a ypresp_order structure.
200 */
201bool
202xdr_ypresp_order(XDR *xdrs, struct ypresp_order *ps)
203{
204	return ((bool)(xdr_u_int(xdrs, &ps->status) &&
205	    xdr_u_int(xdrs, &ps->ordernum)));
206}
207
208/*
209 * This is like xdr_ypmap_wrap_string except that it serializes/deserializes
210 * an array, instead of a pointer, so xdr_reference can work on the structure
211 * containing the char array itself.
212 */
213static bool
214xdr_ypmaplist_wrap_string(XDR *xdrs, char *pstring)
215{
216	char *s;
217
218	s = pstring;
219	return ((bool)xdr_string(xdrs, &s, YPMAXMAP));
220}
221
222/*
223 * Serializes/deserializes a ypmaplist.
224 */
225static bool
226xdr_ypmaplist(XDR *xdrs, struct ypmaplist **lst)
227{
228	bool_t more_elements;
229	int freeing = (xdrs->x_op == XDR_FREE);
230	struct ypmaplist **next;
231
232	for (;;) {
233		more_elements = (*lst != NULL);
234
235		if (!xdr_bool(xdrs, &more_elements))
236			return (FALSE);
237
238		if (!more_elements)
239			return (TRUE);  /* All done */
240
241		if (freeing)
242			next = &((*lst)->ypml_next);
243
244		if (!xdr_reference(xdrs, (caddr_t *)lst,
245			(uint_t)sizeof (struct ypmaplist),
246		    (xdrproc_t)xdr_ypmaplist_wrap_string))
247			return (FALSE);
248
249		lst = (freeing) ? next : &((*lst)->ypml_next);
250	}
251	/*NOTREACHED*/
252}
253
254/*
255 * Serializes/deserializes a ypresp_maplist.
256 */
257bool
258xdr_ypresp_maplist(XDR *xdrs, struct ypresp_maplist *ps)
259{
260	return ((bool)(xdr_u_int(xdrs, &ps->status) &&
261		xdr_ypmaplist(xdrs, &ps->list)));
262}
263
264/*
265 * Serializes/deserializes a yppushresp_xfr structure.
266 */
267bool
268xdr_yppushresp_xfr(XDR *xdrs, struct yppushresp_xfr *ps)
269{
270	return ((bool)(xdr_u_int(xdrs, &ps->transid) &&
271	    xdr_u_int(xdrs, &ps->status)));
272}
273
274
275/*
276 * Serializes/deserializes a ypreq_xfr structure.
277 */
278bool
279xdr_ypreq_newxfr(XDR *xdrs, struct ypreq_newxfr *ps)
280{
281	return ((bool)(xdr_ypmap_parms(xdrs, &ps->map_parms) &&
282	    xdr_u_int(xdrs, &ps->transid) &&
283	    xdr_u_int(xdrs, &ps->proto) &&
284	    xdr_string(xdrs, &ps->name, 256)));
285}
286
287/*
288 * Serializes/deserializes a ypreq_xfr structure.
289 */
290bool
291xdr_ypreq_xfr(XDR *xdrs, struct ypreq_xfr *ps)
292{
293	return ((bool)(xdr_ypmap_parms(xdrs, &ps->map_parms) &&
294	    xdr_u_int(xdrs, &ps->transid) &&
295	    xdr_u_int(xdrs, &ps->proto) &&
296	    xdr_u_short(xdrs, &ps->port)));
297}
298
299
300/*
301 * Serializes/deserializes a stream of struct ypresp_key_val's.  This is used
302 * only by the client side of the batch enumerate operation.
303 */
304bool
305xdr_ypall(XDR *xdrs, struct ypall_callback *callback)
306{
307	bool_t more;
308	struct ypresp_key_val kv;
309	char keybuf[YPMAXRECORD];
310	char valbuf[YPMAXRECORD];
311
312	if (xdrs->x_op == XDR_ENCODE)
313		return (FALSE);
314
315	if (xdrs->x_op == XDR_FREE)
316		return (TRUE);
317
318	kv.keydat.dptr = keybuf;
319	kv.valdat.dptr = valbuf;
320	kv.keydat.dsize = YPMAXRECORD;
321	kv.valdat.dsize = YPMAXRECORD;
322
323	for (;;) {
324		if (!xdr_bool(xdrs, &more))
325			return (FALSE);
326
327		if (!more)
328			return (TRUE);
329
330		if (!xdr_ypresp_key_val(xdrs, &kv))
331			return (FALSE);
332		if ((*callback->foreach)(kv.status, kv.keydat.dptr,
333			    kv.keydat.dsize, kv.valdat.dptr, kv.valdat.dsize,
334			    callback->data))
335			return (TRUE);
336	}
337}
338
339bool_t
340xdr_netconfig(XDR *xdrs, struct netconfig *objp)
341{
342	if (!xdr_string(xdrs, &objp->nc_netid, ~0))
343		return (FALSE);
344	if (!xdr_u_int(xdrs, &objp->nc_semantics))
345		return (FALSE);
346	if (!xdr_u_int(xdrs, &objp->nc_flag))
347		return (FALSE);
348	if (!xdr_string(xdrs, &objp->nc_protofmly, ~0))
349		return (FALSE);
350	if (!xdr_string(xdrs, &objp->nc_proto, ~0))
351		return (FALSE);
352	if (!xdr_string(xdrs, &objp->nc_device, ~0))
353		return (FALSE);
354	if (!xdr_array(xdrs, (char **)&objp->nc_lookups,
355		(uint_t *)&objp->nc_nlookups, 100, sizeof (char *),
356		xdr_wrapstring))
357		return (FALSE);
358	return ((bool)xdr_vector(xdrs, (char *)objp->nc_unused,
359		8, sizeof (uint_t), xdr_u_int));
360}
361