xref: /titanic_41/usr/src/cmd/fs.d/autofs/autod_xdr.c (revision 2b2a8a5e98b489c58877f7b40bd5d13509c9fa15)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * autod_xdr.c
23  *
24  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 /*
31  * This file can not be automatically generated by rpcgen from
32  * autofs_prot.x because of the xdr routines that provide readdir
33  * support, and my own implementation of xdr_autofs_netbuf().
34  */
35 
36 #include <sys/vfs.h>
37 #include <sys/sysmacros.h>		/* includes roundup() */
38 #include <string.h>
39 #include <rpcsvc/autofs_prot.h>
40 #include <rpc/xdr.h>
41 #include <sys/pathconf.h>
42 #include <rpc/auth.h>
43 #include <rpc/rpcsec_gss.h>
44 #include <nfs/mount.h>
45 #include <sys/thread.h>
46 #include <sys/utsname.h>
47 #include <nfs/rnode.h>
48 
49 #define	FS_NFS2	2
50 #define	FS_NFS3	3
51 #define	FS_NFS4	4
52 #define	NFS4_FHSIZE 128
53 
54 static bool_t
55 xdr_nfs_args(XDR *xdrs, struct nfs_args *objp);
56 
57 static bool_t
58 xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp);
59 
60 static bool_t
61 xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp);
62 
63 
64 bool_t
65 xdr_autofs_stat(register XDR *xdrs, autofs_stat *objp)
66 {
67 	if (!xdr_enum(xdrs, (enum_t *)objp))
68 		return (FALSE);
69 	return (TRUE);
70 }
71 
72 bool_t
73 xdr_autofs_action(register XDR *xdrs, autofs_action *objp)
74 {
75 	if (!xdr_enum(xdrs, (enum_t *)objp))
76 		return (FALSE);
77 	return (TRUE);
78 }
79 
80 bool_t
81 xdr_linka(register XDR *xdrs, linka *objp)
82 {
83 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
84 		return (FALSE);
85 	if (!xdr_string(xdrs, &objp->link, AUTOFS_MAXPATHLEN))
86 		return (FALSE);
87 	return (TRUE);
88 }
89 
90 bool_t
91 xdr_autofs_netbuf(xdrs, objp)
92 	XDR *xdrs;
93 	struct netbuf *objp;
94 {
95 	bool_t dummy;
96 
97 	if (!xdr_u_int(xdrs, &objp->maxlen)) {
98 		return (FALSE);
99 	}
100 	dummy = xdr_bytes(xdrs, (char **)&(objp->buf),
101 			(uint_t *)&(objp->len), objp->maxlen);
102 	return (dummy);
103 }
104 
105 bool_t
106 xdr_autofs_args(register XDR *xdrs, autofs_args *objp)
107 {
108 	if (!xdr_autofs_netbuf(xdrs, &objp->addr))
109 		return (FALSE);
110 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
111 		return (FALSE);
112 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
113 		return (FALSE);
114 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
115 		return (FALSE);
116 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
117 		return (FALSE);
118 	if (!xdr_string(xdrs, &objp->key, AUTOFS_MAXCOMPONENTLEN))
119 		return (FALSE);
120 	if (!xdr_int(xdrs, &objp->mount_to))
121 		return (FALSE);
122 	if (!xdr_int(xdrs, &objp->rpc_to))
123 		return (FALSE);
124 	if (!xdr_int(xdrs, &objp->direct))
125 		return (FALSE);
126 	return (TRUE);
127 }
128 
129 bool_t
130 xdr_knetconfig(xdrs, objp)
131 	XDR *xdrs;
132 struct knetconfig *objp;
133 {
134 
135 	rpc_inline_t *buf;
136 
137 	int i;
138 
139 	if (xdrs->x_op == XDR_ENCODE) {
140 		if (!xdr_u_int(xdrs, &objp->knc_semantics))
141 			return (FALSE);
142 		if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE))
143 			return (FALSE);
144 		if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE))
145 			return (FALSE);
146 		if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev))
147 			return (FALSE);
148 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
149 		if (buf == NULL) {
150 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
151 				sizeof (uint_t), (xdrproc_t)xdr_u_int))
152 				return (FALSE);
153 		} else {
154 #if defined(_LP64) || defined(_KERNEL)
155 			{
156 				uint_t *genp;
157 
158 				for (i = 0, genp = objp->knc_unused; i < 8;
159 				    i++) {
160 					IXDR_PUT_U_INT32(buf, *genp++);
161 				}
162 			}
163 #else
164 			{
165 				uint_t *genp;
166 
167 				for (i = 0, genp = objp->knc_unused; i < 8;
168 				    i++) {
169 					IXDR_PUT_U_LONG(buf, *genp++);
170 				}
171 			}
172 #endif
173 		}
174 		return (TRUE);
175 
176 	}
177 	if (!xdr_u_int(xdrs, &objp->knc_semantics))
178 		return (FALSE);
179 	if (!xdr_string(xdrs, &objp->knc_protofmly, KNC_STRSIZE))
180 		return (FALSE);
181 	if (!xdr_string(xdrs, &objp->knc_proto, KNC_STRSIZE))
182 		return (FALSE);
183 
184 	if (!xdr_u_int(xdrs, (uint_t *)&objp->knc_rdev))
185 		return (FALSE);
186 	if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
187 		sizeof (uint_t), (xdrproc_t)xdr_u_int))
188 		return (FALSE);
189 	return (TRUE);
190 }
191 
192 
193 bool_t
194 xdr_pathcnf(XDR *xdrs, struct pathcnf *objp)
195 {
196 
197 	rpc_inline_t *buf;
198 
199 	int i;
200 
201 	if (xdrs->x_op == XDR_ENCODE) {
202 		buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
203 		if (buf == NULL) {
204 			if (!xdr_int(xdrs, &objp->pc_link_max))
205 				return (FALSE);
206 			if (!xdr_short(xdrs, &objp->pc_max_canon))
207 				return (FALSE);
208 			if (!xdr_short(xdrs, &objp->pc_max_input))
209 				return (FALSE);
210 			if (!xdr_short(xdrs, &objp->pc_name_max))
211 				return (FALSE);
212 			if (!xdr_short(xdrs, &objp->pc_path_max))
213 				return (FALSE);
214 			if (!xdr_short(xdrs, &objp->pc_pipe_buf))
215 				return (FALSE);
216 		} else {
217 #if defined(_LP64) || defined(_KERNEL)
218 			IXDR_PUT_INT32(buf, objp->pc_link_max);
219 			IXDR_PUT_SHORT(buf, objp->pc_max_canon);
220 			IXDR_PUT_SHORT(buf, objp->pc_max_input);
221 			IXDR_PUT_SHORT(buf, objp->pc_name_max);
222 			IXDR_PUT_SHORT(buf, objp->pc_path_max);
223 			IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
224 #else
225 			IXDR_PUT_LONG(buf, objp->pc_link_max);
226 			IXDR_PUT_SHORT(buf, objp->pc_max_canon);
227 			IXDR_PUT_SHORT(buf, objp->pc_max_input);
228 			IXDR_PUT_SHORT(buf, objp->pc_name_max);
229 			IXDR_PUT_SHORT(buf, objp->pc_path_max);
230 			IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
231 #endif
232 		}
233 		if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
234 			return (FALSE);
235 		if (!xdr_char(xdrs, &objp->pc_xxx))
236 			return (FALSE);
237 		buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT);
238 		if (buf == NULL) {
239 			if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N,
240 				sizeof (short), (xdrproc_t)xdr_short))
241 				return (FALSE);
242 		} else {
243 #if defined(_LP64) || defined(_KERNEL)
244 				short *genp;
245 
246 				for (i = 0, genp = objp->pc_mask; i < _PC_N;
247 				    i++) {
248 					IXDR_PUT_SHORT(buf, *genp++);
249 				}
250 #else
251 				short *genp;
252 
253 				for (i = 0, genp = objp->pc_mask; i < _PC_N;
254 				    i++) {
255 					IXDR_PUT_SHORT(buf, *genp++);
256 				}
257 #endif
258 		}
259 		return (TRUE);
260 	} else if (xdrs->x_op == XDR_DECODE) {
261 		buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
262 		if (buf == NULL) {
263 			if (!xdr_int(xdrs, &objp->pc_link_max))
264 				return (FALSE);
265 			if (!xdr_short(xdrs, &objp->pc_max_canon))
266 				return (FALSE);
267 			if (!xdr_short(xdrs, &objp->pc_max_input))
268 				return (FALSE);
269 			if (!xdr_short(xdrs, &objp->pc_name_max))
270 				return (FALSE);
271 			if (!xdr_short(xdrs, &objp->pc_path_max))
272 				return (FALSE);
273 			if (!xdr_short(xdrs, &objp->pc_pipe_buf))
274 				return (FALSE);
275 		} else {
276 #if defined(_LP64) || defined(_KERNEL)
277 			objp->pc_link_max = IXDR_GET_INT32(buf);
278 			objp->pc_max_canon = IXDR_GET_SHORT(buf);
279 			objp->pc_max_input = IXDR_GET_SHORT(buf);
280 			objp->pc_name_max = IXDR_GET_SHORT(buf);
281 			objp->pc_path_max = IXDR_GET_SHORT(buf);
282 			objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
283 #else
284 			objp->pc_link_max = IXDR_GET_LONG(buf);
285 			objp->pc_max_canon = IXDR_GET_SHORT(buf);
286 			objp->pc_max_input = IXDR_GET_SHORT(buf);
287 			objp->pc_name_max = IXDR_GET_SHORT(buf);
288 			objp->pc_path_max = IXDR_GET_SHORT(buf);
289 			objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
290 #endif
291 		}
292 		if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
293 			return (FALSE);
294 		if (!xdr_char(xdrs, &objp->pc_xxx))
295 			return (FALSE);
296 		buf = XDR_INLINE(xdrs, (_PC_N) * BYTES_PER_XDR_UNIT);
297 		if (buf == NULL) {
298 			if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N,
299 				sizeof (short), (xdrproc_t)xdr_short))
300 				return (FALSE);
301 		} else {
302 #if defined(_LP64) || defined(_KERNEL)
303 				short *genp;
304 
305 				for (i = 0, genp = objp->pc_mask; i < _PC_N;
306 				    i++) {
307 					*genp++ = IXDR_GET_SHORT(buf);
308 				}
309 #else
310 				short *genp;
311 
312 				for (i = 0, genp = objp->pc_mask;
313 				    i < _PC_N; i++) {
314 					*genp++ = IXDR_GET_SHORT(buf);
315 				}
316 #endif
317 		}
318 		return (TRUE);
319 	}
320 
321 	if (!xdr_int(xdrs, &objp->pc_link_max))
322 		return (FALSE);
323 	if (!xdr_short(xdrs, &objp->pc_max_canon))
324 		return (FALSE);
325 	if (!xdr_short(xdrs, &objp->pc_max_input))
326 		return (FALSE);
327 	if (!xdr_short(xdrs, &objp->pc_name_max))
328 		return (FALSE);
329 	if (!xdr_short(xdrs, &objp->pc_path_max))
330 		return (FALSE);
331 	if (!xdr_short(xdrs, &objp->pc_pipe_buf))
332 		return (FALSE);
333 	if (!xdr_char(xdrs, (char *)&objp->pc_vdisable))
334 		return (FALSE);
335 	if (!xdr_char(xdrs, &objp->pc_xxx))
336 		return (FALSE);
337 	if (!xdr_vector(xdrs, (char *)objp->pc_mask, _PC_N,
338 		sizeof (short), (xdrproc_t)xdr_short))
339 		return (FALSE);
340 	return (TRUE);
341 }
342 
343 bool_t
344 xdr_des_clnt_data(XDR *xdrs, dh_k4_clntdata_t *objp)
345 {
346 
347 	rpc_inline_t *buf;
348 
349 	if (!xdr_autofs_netbuf(xdrs, &objp->syncaddr))
350 		return (FALSE);
351 	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
352 		sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
353 		return (FALSE);
354 	if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
355 		return (FALSE);
356 	if (!xdr_int(xdrs, &objp->netnamelen))
357 		return (FALSE);
358 	return (TRUE);
359 }
360 
361 bool_t
362 xdr_gss_clnt_data(XDR *xdrs, struct gss_clnt_data *objp)
363 {
364 
365 	rpc_inline_t *buf;
366 
367 
368 	if (!xdr_u_int(xdrs, &objp->mechanism.length))
369 		return (FALSE);
370 	if (!xdr_enum(xdrs, (enum_t *)&objp->service))
371 		return (FALSE);
372 	if (!xdr_opaque(xdrs, objp->mechanism.elements,
373 		objp->mechanism.length))
374 		return (FALSE);
375 	if (!xdr_vector(xdrs, (char *)objp->uname, MAX_NAME_LEN,
376 		sizeof (char), (xdrproc_t)xdr_char))
377 		return (FALSE);
378 	if (!xdr_vector(xdrs, (char *)objp->inst, MAX_NAME_LEN,
379 		sizeof (char), (xdrproc_t)xdr_char))
380 		return (FALSE);
381 	if (!xdr_vector(xdrs, (char *)objp->realm, MAX_NAME_LEN,
382 		sizeof (char), (xdrproc_t)xdr_char))
383 		return (FALSE);
384 	if (!xdr_u_int(xdrs, &objp->qop))
385 		return (FALSE);
386 	return (TRUE);
387 }
388 
389 bool_t
390 xdr_sec_data(XDR *xdrs, struct sec_data *objp)
391 {
392 
393 	rpc_inline_t *buf;
394 
395 	if (!xdr_u_int(xdrs, &objp->secmod))
396 		return (FALSE);
397 	if (!xdr_u_int(xdrs, &objp->rpcflavor))
398 		return (FALSE);
399 	if (!xdr_int(xdrs, &objp->flags))
400 		return (FALSE);
401 	if (!xdr_uid_t(xdrs, &objp->uid))
402 		return (FALSE);
403 
404 	switch (objp->rpcflavor) {
405 	case AUTH_NONE:
406 	case AUTH_UNIX:
407 	case AUTH_LOOPBACK:
408 		break;
409 	case AUTH_DES:
410 		if (!xdr_pointer(xdrs, (char **)&objp->data,
411 			sizeof (dh_k4_clntdata_t),
412 			(xdrproc_t)xdr_des_clnt_data))
413 			return (FALSE);
414 		break;
415 	case RPCSEC_GSS:
416 		if (!xdr_pointer(xdrs, (char **)&objp->data,
417 			sizeof (gss_clntdata_t),
418 			(xdrproc_t)xdr_gss_clnt_data))
419 			return (FALSE);
420 		break;
421 	default:
422 		return (FALSE);
423 	}
424 
425 	return (TRUE);
426 }
427 
428 bool_t
429 xdr_nfs2_fh(XDR *xdrs, void *objp)
430 {
431 	if (!xdr_opaque(xdrs, (char *)objp, NFS_FHSIZE))
432 		return (B_FALSE);
433 	return (B_TRUE);
434 }
435 
436 bool_t
437 xdr_nfs3_fhandle(XDR *xdrs, nfs_fhandle *objp)
438 {
439 	if (!xdr_int(xdrs, &objp->fh_len))
440 		return (B_FALSE);
441 	if (!xdr_opaque(xdrs, (char *)&objp->fh_buf, objp->fh_len))
442 		return (B_FALSE);
443 	return (B_TRUE);
444 }
445 
446 bool_t
447 xdr_nfs(XDR *xdrs, struct nfs_args *objp, int nfsv)
448 {
449 
450 	rpc_inline_t *buf;
451 
452 	if (objp == NULL)
453 		return (TRUE);
454 
455 	if (xdrs->x_op == XDR_ENCODE) {
456 		if (!xdr_pointer(xdrs, (char **)&objp->addr,
457 			sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
458 			return (FALSE);
459 		if (!xdr_pointer(xdrs, (char **)&objp->syncaddr,
460 			sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
461 			return (FALSE);
462 		if (!xdr_pointer(xdrs, (char **)&objp->knconf,
463 			sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
464 			return (FALSE);
465 		if (!xdr_string(xdrs, &objp->hostname, SYS_NMLN))
466 			return (FALSE);
467 		if (!xdr_string(xdrs, &objp->netname, SYS_NMLN))
468 			return (FALSE);
469 		if (nfsv == FS_NFS4) {
470 			if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE))
471 				return (B_FALSE);
472 		} else if (nfsv == FS_NFS3) {
473 			if (!xdr_pointer(xdrs, (char **)&objp->fh,
474 				sizeof (nfs_fhandle),
475 				(xdrproc_t)xdr_nfs3_fhandle))
476 				return (B_FALSE);
477 		} else {
478 			if (!xdr_pointer(xdrs, (char **)&objp->fh,
479 				NFS_FHSIZE,
480 				(xdrproc_t)xdr_nfs2_fh))
481 				return (B_FALSE);
482 		}
483 		buf = XDR_INLINE(xdrs, 9 * BYTES_PER_XDR_UNIT);
484 		if (buf == NULL) {
485 			if (!xdr_int(xdrs, &objp->flags))
486 				return (FALSE);
487 			if (!xdr_int(xdrs, &objp->wsize))
488 				return (FALSE);
489 			if (!xdr_int(xdrs, &objp->rsize))
490 				return (FALSE);
491 			if (!xdr_int(xdrs, &objp->timeo))
492 				return (FALSE);
493 			if (!xdr_int(xdrs, &objp->retrans))
494 				return (FALSE);
495 			if (!xdr_int(xdrs, &objp->acregmin))
496 				return (FALSE);
497 			if (!xdr_int(xdrs, &objp->acregmax))
498 				return (FALSE);
499 			if (!xdr_int(xdrs, &objp->acdirmin))
500 				return (FALSE);
501 			if (!xdr_int(xdrs, &objp->acdirmax))
502 				return (FALSE);
503 		} else {
504 #if defined(_LP64) || defined(_KERNEL)
505 			IXDR_PUT_INT32(buf, objp->flags);
506 			IXDR_PUT_INT32(buf, objp->wsize);
507 			IXDR_PUT_INT32(buf, objp->rsize);
508 			IXDR_PUT_INT32(buf, objp->timeo);
509 			IXDR_PUT_INT32(buf, objp->retrans);
510 			IXDR_PUT_INT32(buf, objp->acregmin);
511 			IXDR_PUT_INT32(buf, objp->acregmax);
512 			IXDR_PUT_INT32(buf, objp->acdirmin);
513 			IXDR_PUT_INT32(buf, objp->acdirmax);
514 #else
515 			IXDR_PUT_LONG(buf, objp->flags);
516 			IXDR_PUT_LONG(buf, objp->wsize);
517 			IXDR_PUT_LONG(buf, objp->rsize);
518 			IXDR_PUT_LONG(buf, objp->timeo);
519 			IXDR_PUT_LONG(buf, objp->retrans);
520 			IXDR_PUT_LONG(buf, objp->acregmin);
521 			IXDR_PUT_LONG(buf, objp->acregmax);
522 			IXDR_PUT_LONG(buf, objp->acdirmin);
523 			IXDR_PUT_LONG(buf, objp->acdirmax);
524 #endif
525 		}
526 		if (!xdr_pointer(xdrs, (char **)&objp->pathconf,
527 			sizeof (struct pathcnf),
528 			(xdrproc_t)xdr_pathcnf))
529 			return (FALSE);
530 		if (!xdr_int(xdrs, &objp->nfs_args_ext))
531 			return (FALSE);
532 		if (!xdr_pointer(xdrs,
533 			(char **)&objp->nfs_ext_u.nfs_extA.secdata,
534 			sizeof (struct sec_data),
535 			(xdrproc_t)xdr_sec_data))
536 			return (FALSE);
537 		if (objp->nfs_args_ext == NFS_ARGS_EXTB) {
538 			if (nfsv == FS_NFS4) {
539 				if (!xdr_pointer(xdrs,
540 					(char **)&objp->nfs_ext_u.nfs_extB.next,
541 					sizeof (struct nfs_args),
542 					(xdrproc_t)xdr_nfs4_args))
543 					return (FALSE);
544 			} else if (nfsv == FS_NFS3) {
545 				if (!xdr_pointer(xdrs,
546 					(char **)&objp->nfs_ext_u.nfs_extB.next,
547 					sizeof (struct nfs_args),
548 					(xdrproc_t)xdr_nfs3_args))
549 					return (FALSE);
550 			} else {
551 				if (!xdr_pointer(xdrs,
552 					(char **)&objp->nfs_ext_u.nfs_extB.next,
553 					sizeof (struct nfs_args),
554 					(xdrproc_t)xdr_nfs_args))
555 					return (FALSE);
556 			}
557 		}
558 		return (TRUE);
559 	}
560 
561 	/* Not a DECODE operation */
562 	if (!xdr_pointer(xdrs, (char **)&objp->addr,
563 		sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
564 		return (FALSE);
565 	if (!xdr_pointer(xdrs, (char **)&objp->syncaddr,
566 		sizeof (struct netbuf), (xdrproc_t)xdr_autofs_netbuf))
567 		return (FALSE);
568 	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
569 		sizeof (struct knetconfig), (xdrproc_t)xdr_knetconfig))
570 		return (FALSE);
571 	if (!xdr_pointer(xdrs, (char **)&objp->hostname,
572 		sizeof (char), (xdrproc_t)xdr_char))
573 		return (FALSE);
574 	if (!xdr_pointer(xdrs, (char **)&objp->netname,
575 		sizeof (char), (xdrproc_t)xdr_char))
576 		return (FALSE);
577 	if (nfsv == FS_NFS4) {
578 		if (!xdr_string(xdrs, &objp->fh, NFS4_FHSIZE))
579 			return (B_FALSE);
580 	} else if (nfsv == FS_NFS3) {
581 		if (!xdr_pointer(xdrs, (char **)&objp->fh,
582 			sizeof (nfs_fhandle),
583 			(xdrproc_t)xdr_nfs3_fhandle))
584 			return (B_FALSE);
585 	} else {
586 		if (!xdr_pointer(xdrs, (char **)&objp->fh,
587 			NFS_FHSIZE,
588 			(xdrproc_t)xdr_nfs2_fh))
589 			return (B_FALSE);
590 	}
591 
592 	if (!xdr_int(xdrs, &objp->flags))
593 		return (FALSE);
594 	if (!xdr_int(xdrs, &objp->wsize))
595 		return (FALSE);
596 	if (!xdr_int(xdrs, &objp->rsize))
597 		return (FALSE);
598 	if (!xdr_int(xdrs, &objp->timeo))
599 		return (FALSE);
600 	if (!xdr_int(xdrs, &objp->retrans))
601 		return (FALSE);
602 	if (!xdr_int(xdrs, &objp->acregmin))
603 		return (FALSE);
604 	if (!xdr_int(xdrs, &objp->acregmax))
605 		return (FALSE);
606 	if (!xdr_int(xdrs, &objp->acdirmin))
607 		return (FALSE);
608 	if (!xdr_int(xdrs, &objp->acdirmax))
609 		return (FALSE);
610 	if (!xdr_pointer(xdrs, (char **)&objp->pathconf,
611 		sizeof (struct pathcnf), (xdrproc_t)xdr_pathcnf))
612 		return (FALSE);
613 	if (!xdr_int(xdrs, &objp->nfs_args_ext))
614 		return (FALSE);
615 	if (!xdr_pointer(xdrs, (char **)&objp->nfs_ext_u.nfs_extA.secdata,
616 		sizeof (struct sec_data), (xdrproc_t)xdr_sec_data))
617 		return (FALSE);
618 	if (objp->nfs_args_ext == NFS_ARGS_EXTB) {
619 		if (nfsv == FS_NFS4) {
620 			if (!xdr_pointer(xdrs,
621 				(char **)&objp->nfs_ext_u.nfs_extB.next,
622 				sizeof (struct nfs_args),
623 				(xdrproc_t)xdr_nfs4_args))
624 				return (FALSE);
625 		} else if (nfsv == FS_NFS3) {
626 			if (!xdr_pointer(xdrs,
627 				(char **)&objp->nfs_ext_u.nfs_extB.next,
628 				sizeof (struct nfs_args),
629 				(xdrproc_t)xdr_nfs3_args))
630 				return (FALSE);
631 		} else {
632 			if (!xdr_pointer(xdrs,
633 				(char **)&objp->nfs_ext_u.nfs_extB.next,
634 				sizeof (struct nfs_args),
635 				(xdrproc_t)xdr_nfs_args))
636 				return (FALSE);
637 		}
638 
639 	}
640 	return (TRUE);
641 }
642 
643 static bool_t
644 xdr_nfs4_args(XDR *xdrs, struct nfs_args *objp)
645 {
646 	return (xdr_nfs(xdrs, objp, FS_NFS4));
647 }
648 
649 static bool_t
650 xdr_nfs3_args(XDR *xdrs, struct nfs_args *objp)
651 {
652 	return (xdr_nfs(xdrs, objp, FS_NFS3));
653 }
654 
655 static bool_t
656 xdr_nfs_args(XDR *xdrs, struct nfs_args *objp)
657 {
658 	return (xdr_nfs(xdrs, objp, FS_NFS2));
659 }
660 
661 
662 bool_t
663 xdr_mounta(register XDR *xdrs, struct mounta *objp)
664 {
665 	if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN))
666 		return (FALSE);
667 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
668 		return (FALSE);
669 	if (!xdr_int(xdrs, &objp->flags))
670 		return (FALSE);
671 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
672 		return (FALSE);
673 	if (strncmp(objp->fstype, "autofs", 6) == 0) {
674 		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
675 			sizeof (autofs_args),
676 			(xdrproc_t)xdr_autofs_args))
677 			return (FALSE);
678 	} else if (strncmp(objp->fstype, "nfs4", 4) == 0) {
679 		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
680 			sizeof (struct nfs_args),
681 			(xdrproc_t)xdr_nfs4_args))
682 			return (FALSE);
683 	} else if (strncmp(objp->fstype, "nfs3", 4) == 0) {
684 		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
685 			sizeof (struct nfs_args),
686 			(xdrproc_t)xdr_nfs3_args))
687 			return (FALSE);
688 	} else {
689 		if (!xdr_pointer(xdrs, (char **)&objp->dataptr,
690 			sizeof (struct nfs_args),
691 			(xdrproc_t)xdr_nfs_args))
692 			return (FALSE);
693 	}
694 	if (!xdr_int(xdrs, &objp->datalen))
695 		return (FALSE);
696 
697 	if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
698 		return (FALSE);
699 	if (!xdr_int(xdrs, &objp->optlen))
700 		return (FALSE);
701 	return (TRUE);
702 }
703 
704 bool_t
705 xdr_action_list_entry(register XDR *xdrs, action_list_entry *objp)
706 {
707 	if (!xdr_autofs_action(xdrs, &objp->action))
708 		return (FALSE);
709 	switch (objp->action) {
710 	case AUTOFS_MOUNT_RQ:
711 		if (!xdr_mounta(xdrs, &objp->action_list_entry_u.mounta))
712 			return (FALSE);
713 		break;
714 	case AUTOFS_LINK_RQ:
715 		if (!xdr_linka(xdrs, &objp->action_list_entry_u.linka))
716 			return (FALSE);
717 		break;
718 	}
719 	return (TRUE);
720 }
721 
722 bool_t
723 xdr_action_list(register XDR *xdrs, action_list *objp)
724 {
725 	if (!xdr_action_list_entry(xdrs, &objp->action))
726 		return (FALSE);
727 	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (action_list),
728 			(xdrproc_t)xdr_action_list))
729 		return (FALSE);
730 	return (TRUE);
731 }
732 
733 bool_t
734 xdr_umntrequest(register XDR *xdrs, umntrequest *objp)
735 {
736 	if (!xdr_bool_t(xdrs, &objp->isdirect))
737 		return (FALSE);
738 	if (!xdr_string(xdrs, &objp->mntresource, AUTOFS_MAXPATHLEN))
739 		return (FALSE);
740 	if (!xdr_string(xdrs, &objp->mntpnt, AUTOFS_MAXPATHLEN))
741 		return (FALSE);
742 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
743 		return (FALSE);
744 	if (!xdr_string(xdrs, &objp->mntopts, AUTOFS_MAXOPTSLEN))
745 		return (FALSE);
746 	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (umntrequest),
747 			(xdrproc_t)xdr_umntrequest))
748 		return (FALSE);
749 	return (TRUE);
750 }
751 
752 bool_t
753 xdr_umntres(register XDR *xdrs, umntres *objp)
754 {
755 	if (!xdr_int(xdrs, &objp->status))
756 		return (FALSE);
757 	return (TRUE);
758 }
759 
760 bool_t
761 xdr_autofs_res(xdrs, objp)
762 	register XDR *xdrs;
763 	autofs_res *objp;
764 {
765 	if (!xdr_enum(xdrs, (enum_t *)objp))
766 		return (FALSE);
767 	return (TRUE);
768 }
769 
770 bool_t
771 xdr_autofs_lookupargs(xdrs, objp)
772 	register XDR *xdrs;
773 	autofs_lookupargs *objp;
774 {
775 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
776 		return (FALSE);
777 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
778 		return (FALSE);
779 	if (!xdr_string(xdrs, &objp->name, AUTOFS_MAXCOMPONENTLEN))
780 		return (FALSE);
781 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
782 		return (FALSE);
783 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
784 		return (FALSE);
785 	if (!xdr_bool_t(xdrs, &objp->isdirect))
786 		return (FALSE);
787 	if (!xdr_u_int(xdrs, (uint_t *)&objp->uid))
788 		return (FALSE);
789 	return (TRUE);
790 }
791 
792 bool_t
793 xdr_mount_result_type(xdrs, objp)
794 	register XDR *xdrs;
795 	mount_result_type *objp;
796 {
797 	if (!xdr_autofs_stat(xdrs, &objp->status))
798 		return (FALSE);
799 	switch (objp->status) {
800 	case AUTOFS_ACTION:
801 		if (!xdr_pointer(xdrs,
802 		    (char **)&objp->mount_result_type_u.list,
803 		    sizeof (action_list), (xdrproc_t)xdr_action_list))
804 			return (FALSE);
805 		break;
806 	case AUTOFS_DONE:
807 		if (!xdr_int(xdrs, &objp->mount_result_type_u.error))
808 			return (FALSE);
809 		break;
810 	}
811 	return (TRUE);
812 }
813 
814 bool_t
815 xdr_autofs_mountres(xdrs, objp)
816 	register XDR *xdrs;
817 	autofs_mountres *objp;
818 {
819 	if (!xdr_mount_result_type(xdrs, &objp->mr_type))
820 		return (FALSE);
821 	if (!xdr_int(xdrs, &objp->mr_verbose))
822 		return (FALSE);
823 	return (TRUE);
824 }
825 bool_t
826 xdr_lookup_result_type(xdrs, objp)
827 	register XDR *xdrs;
828 	lookup_result_type *objp;
829 {
830 	if (!xdr_autofs_action(xdrs, &objp->action))
831 		return (FALSE);
832 	switch (objp->action) {
833 	case AUTOFS_LINK_RQ:
834 		if (!xdr_linka(xdrs, &objp->lookup_result_type_u.lt_linka))
835 			return (FALSE);
836 		break;
837 	}
838 	return (TRUE);
839 }
840 
841 bool_t
842 xdr_autofs_lookupres(xdrs, objp)
843 	register XDR *xdrs;
844 	autofs_lookupres *objp;
845 {
846 	if (!xdr_autofs_res(xdrs, &objp->lu_res))
847 		return (FALSE);
848 	if (!xdr_lookup_result_type(xdrs, &objp->lu_type))
849 		return (FALSE);
850 	if (!xdr_int(xdrs, &objp->lu_verbose))
851 		return (FALSE);
852 	return (TRUE);
853 }
854 
855 /*
856  * ******************************************************
857  * Readdir XDR support
858  * ******************************************************
859  */
860 
861 bool_t
862 xdr_autofs_rddirargs(xdrs, objp)
863 	register XDR *xdrs;
864 	autofs_rddirargs *objp;
865 {
866 	if (!xdr_string(xdrs, &objp->rda_map, AUTOFS_MAXPATHLEN))
867 		return (FALSE);
868 	if (!xdr_u_int(xdrs, &objp->rda_offset))
869 		return (FALSE);
870 	if (!xdr_u_int(xdrs, &objp->rda_count))
871 		return (FALSE);
872 	if (!xdr_u_int(xdrs, (uint_t *)&objp->uid))
873 		return (FALSE);
874 	return (TRUE);
875 }
876 
877 /*
878  * Directory read reply:
879  * union (enum autofs_res) {
880  *	AUTOFS_OK: entlist;
881  *		 boolean eof;
882  *	default:
883  * }
884  *
885  * Directory entries
886  *	struct  direct {
887  *		off_t   d_off;			* offset of next entry *
888  *		u_long  d_fileno;		* inode number of entry *
889  *		u_short d_reclen;		* length of this record *
890  *		u_short d_namlen;		* length of string in d_name *
891  *		char    d_name[MAXNAMLEN + 1];	* name no longer than this *
892  *	};
893  * are on the wire as:
894  * union entlist (boolean valid) {
895  * 	TRUE:	struct otw_dirent;
896  *		u_long nxtoffset;
897  *		union entlist;
898  *	FALSE:
899  * }
900  * where otw_dirent is:
901  * 	struct dirent {
902  *		u_long	de_fid;
903  *		string	de_name<AUTOFS_MAXPATHLEN>;
904  *	}
905  */
906 
907 #ifdef nextdp
908 #undef nextdp
909 #endif
910 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
911 
912 /*
913  * ENCODE ONLY
914  */
915 bool_t
916 xdr_autofs_putrddirres(xdrs, rddir, reqsize)
917 	XDR *xdrs;
918 	struct autofsrddir *rddir;
919 	uint_t reqsize;			/* requested size */
920 {
921 	struct dirent64 *dp;
922 	char *name;
923 	int size;
924 	uint_t namlen;
925 	bool_t true = TRUE;
926 	bool_t false = FALSE;
927 	int entrysz;
928 	int tofit;
929 	int bufsize;
930 	uint_t ino, off;
931 
932 	bufsize = 1 * BYTES_PER_XDR_UNIT;
933 	for (size = rddir->rddir_size, dp = rddir->rddir_entries;
934 		size > 0;
935 		/* LINTED pointer alignment */
936 		size -= dp->d_reclen, dp = nextdp(dp)) {
937 		if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */) {
938 			return (FALSE);
939 		}
940 		if (dp->d_ino == 0) {
941 			continue;
942 		}
943 		name = dp->d_name;
944 		namlen = strlen(name);
945 		ino = (uint_t)dp->d_ino;
946 		off = (uint_t)dp->d_off;
947 		entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
948 		    roundup(namlen, BYTES_PER_XDR_UNIT);
949 		tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
950 		if (bufsize + tofit > reqsize) {
951 			rddir->rddir_eof = FALSE;
952 			break;
953 		}
954 		if (!xdr_bool(xdrs, &true) ||
955 		    !xdr_u_int(xdrs, &ino) ||
956 		    !xdr_bytes(xdrs, &name, &namlen, AUTOFS_MAXPATHLEN) ||
957 		    !xdr_u_int(xdrs, &off)) {
958 			return (FALSE);
959 		}
960 		bufsize += entrysz;
961 	}
962 	if (!xdr_bool(xdrs, &false)) {
963 		return (FALSE);
964 	}
965 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
966 		return (FALSE);
967 	}
968 	return (TRUE);
969 }
970 
971 #define	DIRENT64_RECLEN(namelen)	\
972 	(((int)(((dirent64_t *)0)->d_name) + 1 + (namelen) + 7) & ~ 7)
973 #define	reclen(namlen)	DIRENT64_RECLEN((namlen))
974 
975 /*
976  * DECODE ONLY
977  */
978 bool_t
979 xdr_autofs_getrddirres(xdrs, rddir)
980 	XDR *xdrs;
981 	struct autofsrddir *rddir;
982 {
983 	struct dirent64 *dp;
984 	uint_t namlen;
985 	int size;
986 	bool_t valid;
987 	int offset = -1;
988 	uint_t fileid;
989 
990 	size = rddir->rddir_size;
991 	dp = rddir->rddir_entries;
992 	for (;;) {
993 		if (!xdr_bool(xdrs, &valid)) {
994 			return (FALSE);
995 		}
996 		if (!valid) {
997 			break;
998 		}
999 		if (!xdr_u_int(xdrs, &fileid) ||
1000 		    !xdr_u_int(xdrs, &namlen)) {
1001 			return (FALSE);
1002 		}
1003 		if (reclen(namlen) > size) {
1004 			rddir->rddir_eof = FALSE;
1005 			goto bufovflw;
1006 		}
1007 		if (!xdr_opaque(xdrs, dp->d_name, namlen)||
1008 		    !xdr_int(xdrs, &offset)) {
1009 			return (FALSE);
1010 		}
1011 		dp->d_ino = fileid;
1012 		dp->d_reclen = reclen(namlen);
1013 		dp->d_name[namlen] = '\0';
1014 		dp->d_off = offset;
1015 		size -= dp->d_reclen;
1016 		/* LINTED pointer alignment */
1017 		dp = nextdp(dp);
1018 	}
1019 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
1020 		return (FALSE);
1021 	}
1022 bufovflw:
1023 	rddir->rddir_size = (char *)dp - (char *)(rddir->rddir_entries);
1024 	rddir->rddir_offset = offset;
1025 	return (TRUE);
1026 }
1027 
1028 bool_t
1029 xdr_autofs_rddirres(register XDR *xdrs, autofs_rddirres *objp)
1030 {
1031 	if (!xdr_enum(xdrs, (enum_t *)&objp->rd_status))
1032 		return (FALSE);
1033 	if (objp->rd_status != AUTOFS_OK)
1034 		return (TRUE);
1035 	if (xdrs->x_op == XDR_ENCODE)
1036 		return (xdr_autofs_putrddirres(
1037 			xdrs, (struct autofsrddir *)&objp->rd_rddir,
1038 			objp->rd_bufsize));
1039 	else if (xdrs->x_op == XDR_DECODE)
1040 		return (xdr_autofs_getrddirres(xdrs,
1041 			(struct autofsrddir *)&objp->rd_rddir));
1042 	else return (FALSE);
1043 }
1044