xref: /illumos-gate/usr/src/cmd/fs.d/autofs/autod_xdr.c (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
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 <stdlib.h>
42 #include <strings.h>
43 
44 bool_t
45 xdr_autofs_stat(register XDR *xdrs, autofs_stat *objp)
46 {
47 	if (!xdr_enum(xdrs, (enum_t *)objp))
48 		return (FALSE);
49 	return (TRUE);
50 }
51 
52 bool_t
53 xdr_autofs_action(register XDR *xdrs, autofs_action *objp)
54 {
55 	if (!xdr_enum(xdrs, (enum_t *)objp))
56 		return (FALSE);
57 	return (TRUE);
58 }
59 
60 bool_t
61 xdr_linka(register XDR *xdrs, linka *objp)
62 {
63 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
64 		return (FALSE);
65 	if (!xdr_string(xdrs, &objp->link, AUTOFS_MAXPATHLEN))
66 		return (FALSE);
67 	return (TRUE);
68 }
69 
70 bool_t
71 xdr_autofs_netbuf(xdrs, objp)
72 	XDR *xdrs;
73 	struct netbuf *objp;
74 {
75 	bool_t dummy;
76 
77 	if (!xdr_u_int(xdrs, &objp->maxlen)) {
78 		return (FALSE);
79 	}
80 	dummy = xdr_bytes(xdrs, (char **)&(objp->buf),
81 			(uint_t *)&(objp->len), objp->maxlen);
82 	return (dummy);
83 }
84 
85 bool_t
86 xdr_autofs_args(register XDR *xdrs, autofs_args *objp)
87 {
88 	if (!xdr_autofs_netbuf(xdrs, &objp->addr))
89 		return (FALSE);
90 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
91 		return (FALSE);
92 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
93 		return (FALSE);
94 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
95 		return (FALSE);
96 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
97 		return (FALSE);
98 	if (!xdr_string(xdrs, &objp->key, AUTOFS_MAXCOMPONENTLEN))
99 		return (FALSE);
100 	if (!xdr_int(xdrs, &objp->mount_to))
101 		return (FALSE);
102 	if (!xdr_int(xdrs, &objp->rpc_to))
103 		return (FALSE);
104 	if (!xdr_int(xdrs, &objp->direct))
105 		return (FALSE);
106 	return (TRUE);
107 }
108 
109 bool_t
110 xdr_mounta(register XDR *xdrs, struct mounta *objp)
111 {
112 	if (!xdr_string(xdrs, &objp->spec, AUTOFS_MAXPATHLEN))
113 		return (FALSE);
114 	if (!xdr_string(xdrs, &objp->dir, AUTOFS_MAXPATHLEN))
115 		return (FALSE);
116 	if (!xdr_int(xdrs, &objp->flags))
117 		return (FALSE);
118 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
119 		return (FALSE);
120 	if (!xdr_pointer(xdrs, (char **)&objp->dataptr, sizeof (autofs_args),
121 	    (xdrproc_t)xdr_autofs_args))
122 		return (FALSE);
123 	if (!xdr_int(xdrs, &objp->datalen))
124 		return (FALSE);
125 	if (!xdr_string(xdrs, &objp->optptr, AUTOFS_MAXOPTSLEN))
126 		return (FALSE);
127 	if (!xdr_int(xdrs, &objp->optlen))
128 		return (FALSE);
129 	return (TRUE);
130 }
131 
132 bool_t
133 xdr_action_list_entry(register XDR *xdrs, action_list_entry *objp)
134 {
135 	if (!xdr_autofs_action(xdrs, &objp->action))
136 		return (FALSE);
137 	switch (objp->action) {
138 	case AUTOFS_MOUNT_RQ:
139 		if (!xdr_mounta(xdrs, &objp->action_list_entry_u.mounta))
140 			return (FALSE);
141 		break;
142 	case AUTOFS_LINK_RQ:
143 		if (!xdr_linka(xdrs, &objp->action_list_entry_u.linka))
144 			return (FALSE);
145 		break;
146 	}
147 	return (TRUE);
148 }
149 
150 bool_t
151 xdr_action_list(XDR *xdrs, action_list *objp)
152 {
153 	action_list *tmp_action_list;
154 	bool_t more_data = TRUE;
155 	bool_t first_objp = TRUE;
156 
157 	if (xdrs->x_op == XDR_DECODE) {
158 		while (more_data) {
159 			if (!xdr_action_list_entry(xdrs, &objp->action))
160 				return (FALSE);
161 			if (!xdr_bool(xdrs, &more_data))
162 				return (FALSE);
163 			if (!more_data) {
164 				objp->next = NULL;
165 				break;
166 			}
167 			if (objp->next == NULL) {
168 				objp->next = (action_list *)
169 				    mem_alloc(sizeof (action_list));
170 				if (objp->next == NULL)
171 					return (FALSE);
172 				bzero(objp->next, sizeof (action_list));
173 			}
174 			objp = objp->next;
175 		}
176 	} else if (xdrs->x_op == XDR_ENCODE) {
177 		while (more_data) {
178 			if (!xdr_action_list_entry(xdrs, &objp->action))
179 				return (FALSE);
180 			objp = objp->next;
181 			if (objp == NULL)
182 				more_data = FALSE;
183 			if (!xdr_bool(xdrs, &more_data))
184 				return (FALSE);
185 		}
186 	} else {
187 		while (more_data) {
188 			if (!xdr_action_list_entry(xdrs, &objp->action))
189 				return (FALSE);
190 			tmp_action_list = objp;
191 			objp = objp->next;
192 			if (objp == NULL)
193 				more_data = FALSE;
194 			if (!first_objp)
195 				mem_free(tmp_action_list, sizeof (action_list));
196 			else
197 				first_objp = FALSE;
198 		}
199 	}
200 	return (TRUE);
201 }
202 
203 bool_t
204 xdr_umntrequest(register XDR *xdrs, umntrequest *objp)
205 {
206 	if (!xdr_bool_t(xdrs, &objp->isdirect))
207 		return (FALSE);
208 	if (!xdr_string(xdrs, &objp->mntresource, AUTOFS_MAXPATHLEN))
209 		return (FALSE);
210 	if (!xdr_string(xdrs, &objp->mntpnt, AUTOFS_MAXPATHLEN))
211 		return (FALSE);
212 	if (!xdr_string(xdrs, &objp->fstype, AUTOFS_MAXCOMPONENTLEN))
213 		return (FALSE);
214 	if (!xdr_string(xdrs, &objp->mntopts, AUTOFS_MAXOPTSLEN))
215 		return (FALSE);
216 	if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (umntrequest),
217 	    (xdrproc_t)xdr_umntrequest))
218 		return (FALSE);
219 	return (TRUE);
220 }
221 
222 bool_t
223 xdr_umntres(register XDR *xdrs, umntres *objp)
224 {
225 	if (!xdr_int(xdrs, &objp->status))
226 		return (FALSE);
227 	return (TRUE);
228 }
229 
230 bool_t
231 xdr_autofs_res(xdrs, objp)
232 	register XDR *xdrs;
233 	autofs_res *objp;
234 {
235 	if (!xdr_enum(xdrs, (enum_t *)objp))
236 		return (FALSE);
237 	return (TRUE);
238 }
239 
240 bool_t
241 xdr_autofs_lookupargs(xdrs, objp)
242 	register XDR *xdrs;
243 	autofs_lookupargs *objp;
244 {
245 	if (!xdr_string(xdrs, &objp->map, AUTOFS_MAXPATHLEN))
246 		return (FALSE);
247 	if (!xdr_string(xdrs, &objp->path, AUTOFS_MAXPATHLEN))
248 		return (FALSE);
249 	if (!xdr_string(xdrs, &objp->name, AUTOFS_MAXCOMPONENTLEN))
250 		return (FALSE);
251 	if (!xdr_string(xdrs, &objp->subdir, AUTOFS_MAXPATHLEN))
252 		return (FALSE);
253 	if (!xdr_string(xdrs, &objp->opts, AUTOFS_MAXOPTSLEN))
254 		return (FALSE);
255 	if (!xdr_bool_t(xdrs, &objp->isdirect))
256 		return (FALSE);
257 	if (!xdr_u_int(xdrs, (uint_t *)&objp->uid))
258 		return (FALSE);
259 	return (TRUE);
260 }
261 
262 bool_t
263 xdr_mount_result_type(xdrs, objp)
264 	register XDR *xdrs;
265 	mount_result_type *objp;
266 {
267 	if (!xdr_autofs_stat(xdrs, &objp->status))
268 		return (FALSE);
269 	switch (objp->status) {
270 	case AUTOFS_ACTION:
271 		if (!xdr_pointer(xdrs,
272 		    (char **)&objp->mount_result_type_u.list,
273 		    sizeof (action_list), (xdrproc_t)xdr_action_list))
274 			return (FALSE);
275 		break;
276 	case AUTOFS_DONE:
277 		if (!xdr_int(xdrs, &objp->mount_result_type_u.error))
278 			return (FALSE);
279 		break;
280 	}
281 	return (TRUE);
282 }
283 
284 bool_t
285 xdr_autofs_mountres(xdrs, objp)
286 	register XDR *xdrs;
287 	autofs_mountres *objp;
288 {
289 	if (!xdr_mount_result_type(xdrs, &objp->mr_type))
290 		return (FALSE);
291 	if (!xdr_int(xdrs, &objp->mr_verbose))
292 		return (FALSE);
293 	return (TRUE);
294 }
295 bool_t
296 xdr_lookup_result_type(xdrs, objp)
297 	register XDR *xdrs;
298 	lookup_result_type *objp;
299 {
300 	if (!xdr_autofs_action(xdrs, &objp->action))
301 		return (FALSE);
302 	switch (objp->action) {
303 	case AUTOFS_LINK_RQ:
304 		if (!xdr_linka(xdrs, &objp->lookup_result_type_u.lt_linka))
305 			return (FALSE);
306 		break;
307 	}
308 	return (TRUE);
309 }
310 
311 bool_t
312 xdr_autofs_lookupres(xdrs, objp)
313 	register XDR *xdrs;
314 	autofs_lookupres *objp;
315 {
316 	if (!xdr_autofs_res(xdrs, &objp->lu_res))
317 		return (FALSE);
318 	if (!xdr_lookup_result_type(xdrs, &objp->lu_type))
319 		return (FALSE);
320 	if (!xdr_int(xdrs, &objp->lu_verbose))
321 		return (FALSE);
322 	return (TRUE);
323 }
324 
325 /*
326  * ******************************************************
327  * Readdir XDR support
328  * ******************************************************
329  */
330 
331 bool_t
332 xdr_autofs_rddirargs(xdrs, objp)
333 	register XDR *xdrs;
334 	autofs_rddirargs *objp;
335 {
336 	if (!xdr_string(xdrs, &objp->rda_map, AUTOFS_MAXPATHLEN))
337 		return (FALSE);
338 	if (!xdr_u_int(xdrs, &objp->rda_offset))
339 		return (FALSE);
340 	if (!xdr_u_int(xdrs, &objp->rda_count))
341 		return (FALSE);
342 	if (!xdr_u_int(xdrs, (uint_t *)&objp->uid))
343 		return (FALSE);
344 	return (TRUE);
345 }
346 
347 /*
348  * Directory read reply:
349  * union (enum autofs_res) {
350  *	AUTOFS_OK: entlist;
351  *		 boolean eof;
352  *	default:
353  * }
354  *
355  * Directory entries
356  *	struct  direct {
357  *		off_t   d_off;			* offset of next entry *
358  *		u_long  d_fileno;		* inode number of entry *
359  *		u_short d_reclen;		* length of this record *
360  *		u_short d_namlen;		* length of string in d_name *
361  *		char    d_name[MAXNAMLEN + 1];	* name no longer than this *
362  *	};
363  * are on the wire as:
364  * union entlist (boolean valid) {
365  * 	TRUE:	struct otw_dirent;
366  *		u_long nxtoffset;
367  *		union entlist;
368  *	FALSE:
369  * }
370  * where otw_dirent is:
371  * 	struct dirent {
372  *		u_long	de_fid;
373  *		string	de_name<AUTOFS_MAXPATHLEN>;
374  *	}
375  */
376 
377 #ifdef nextdp
378 #undef nextdp
379 #endif
380 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
381 
382 /*
383  * ENCODE ONLY
384  */
385 bool_t
386 xdr_autofs_putrddirres(xdrs, rddir, reqsize)
387 	XDR *xdrs;
388 	struct autofsrddir *rddir;
389 	uint_t reqsize;			/* requested size */
390 {
391 	struct dirent64 *dp;
392 	char *name;
393 	int size;
394 	uint_t namlen;
395 	bool_t true = TRUE;
396 	bool_t false = FALSE;
397 	int entrysz;
398 	int tofit;
399 	int bufsize;
400 	uint_t ino, off;
401 
402 	bufsize = 1 * BYTES_PER_XDR_UNIT;
403 	for (size = rddir->rddir_size, dp = rddir->rddir_entries;
404 		size > 0;
405 		/* LINTED pointer alignment */
406 		size -= dp->d_reclen, dp = nextdp(dp)) {
407 		if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */) {
408 			return (FALSE);
409 		}
410 		if (dp->d_ino == 0) {
411 			continue;
412 		}
413 		name = dp->d_name;
414 		namlen = strlen(name);
415 		ino = (uint_t)dp->d_ino;
416 		off = (uint_t)dp->d_off;
417 		entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
418 		    roundup(namlen, BYTES_PER_XDR_UNIT);
419 		tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
420 		if (bufsize + tofit > reqsize) {
421 			rddir->rddir_eof = FALSE;
422 			break;
423 		}
424 		if (!xdr_bool(xdrs, &true) ||
425 		    !xdr_u_int(xdrs, &ino) ||
426 		    !xdr_bytes(xdrs, &name, &namlen, AUTOFS_MAXPATHLEN) ||
427 		    !xdr_u_int(xdrs, &off)) {
428 			return (FALSE);
429 		}
430 		bufsize += entrysz;
431 	}
432 	if (!xdr_bool(xdrs, &false)) {
433 		return (FALSE);
434 	}
435 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
436 		return (FALSE);
437 	}
438 	return (TRUE);
439 }
440 
441 #define	DIRENT64_RECLEN(namelen)	\
442 	(((int)(((dirent64_t *)0)->d_name) + 1 + (namelen) + 7) & ~ 7)
443 #define	reclen(namlen)	DIRENT64_RECLEN((namlen))
444 
445 /*
446  * DECODE ONLY
447  */
448 bool_t
449 xdr_autofs_getrddirres(xdrs, rddir)
450 	XDR *xdrs;
451 	struct autofsrddir *rddir;
452 {
453 	struct dirent64 *dp;
454 	uint_t namlen;
455 	int size;
456 	bool_t valid;
457 	int offset = -1;
458 	uint_t fileid;
459 
460 	size = rddir->rddir_size;
461 	dp = rddir->rddir_entries;
462 	for (;;) {
463 		if (!xdr_bool(xdrs, &valid)) {
464 			return (FALSE);
465 		}
466 		if (!valid) {
467 			break;
468 		}
469 		if (!xdr_u_int(xdrs, &fileid) ||
470 		    !xdr_u_int(xdrs, &namlen)) {
471 			return (FALSE);
472 		}
473 		if (reclen(namlen) > size) {
474 			rddir->rddir_eof = FALSE;
475 			goto bufovflw;
476 		}
477 		if (!xdr_opaque(xdrs, dp->d_name, namlen)||
478 		    !xdr_int(xdrs, &offset)) {
479 			return (FALSE);
480 		}
481 		dp->d_ino = fileid;
482 		dp->d_reclen = reclen(namlen);
483 		dp->d_name[namlen] = '\0';
484 		dp->d_off = offset;
485 		size -= dp->d_reclen;
486 		/* LINTED pointer alignment */
487 		dp = nextdp(dp);
488 	}
489 	if (!xdr_bool(xdrs, &rddir->rddir_eof)) {
490 		return (FALSE);
491 	}
492 bufovflw:
493 	rddir->rddir_size = (char *)dp - (char *)(rddir->rddir_entries);
494 	rddir->rddir_offset = offset;
495 	return (TRUE);
496 }
497 
498 bool_t
499 xdr_autofs_rddirres(register XDR *xdrs, autofs_rddirres *objp)
500 {
501 	if (!xdr_enum(xdrs, (enum_t *)&objp->rd_status))
502 		return (FALSE);
503 	if (objp->rd_status != AUTOFS_OK)
504 		return (TRUE);
505 	if (xdrs->x_op == XDR_ENCODE)
506 		return (xdr_autofs_putrddirres(
507 		    xdrs, (struct autofsrddir *)&objp->rd_rddir,
508 		    objp->rd_bufsize));
509 	else if (xdrs->x_op == XDR_DECODE)
510 		return (xdr_autofs_getrddirres(xdrs,
511 		    (struct autofsrddir *)&objp->rd_rddir));
512 	else return (FALSE);
513 }
514