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  * Copyright 2017 Joyent Inc
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/systm.h>
29 #include <sys/cmn_err.h>
30 #include <sys/kmem.h>
31 #include <sys/cred.h>
32 #include <sys/dirent.h>
33 #include <sys/debug.h>
34 #include <rpc/types.h>
35 #include <nfs/nfs.h>
36 #include <nfs/export.h>
37 #include <rpc/svc.h>
38 #include <rpc/xdr.h>
39 #include <rpc/rpcb_prot.h>
40 #include <rpc/clnt.h>
41 #include <nfs/nfs_log.h>
42 
43 /*
44  * nfsl_principal_name_get - extracts principal from transport struct.
45  * Based on "uts/common/rpc/sec/sec_svc.c" function sec_svc_getcred.
46  */
47 static char *
nfsl_principal_name_get(struct svc_req * req)48 nfsl_principal_name_get(struct svc_req *req)
49 {
50 	char				*principal_name = NULL;
51 	struct authdes_cred		*adc;
52 	rpc_gss_rawcred_t		*rcred;
53 	rpc_gss_ucred_t			*ucred;
54 	void				*cookie;
55 
56 	switch (req->rq_cred.oa_flavor) {
57 	case AUTH_UNIX:
58 	case AUTH_NONE:
59 		/* no principal name provided */
60 		break;
61 
62 	case AUTH_DES:
63 		adc = (struct authdes_cred *)req->rq_clntcred;
64 		CTASSERT(sizeof (struct authdes_cred) <= RQCRED_SIZE);
65 		principal_name = adc->adc_fullname.name;
66 		break;
67 
68 	case RPCSEC_GSS:
69 		(void) rpc_gss_getcred(req, &rcred, &ucred, &cookie);
70 		principal_name = (caddr_t)rcred->client_principal;
71 		break;
72 
73 	default:
74 		break;
75 	}
76 	return (principal_name);
77 }
78 
79 bool_t
xdr_timestruc32_t(XDR * xdrs,timestruc32_t * objp)80 xdr_timestruc32_t(XDR *xdrs, timestruc32_t *objp)
81 {
82 	if (!xdr_int(xdrs, &objp->tv_sec))
83 		return (FALSE);
84 	return (xdr_int(xdrs, &objp->tv_nsec));
85 }
86 
87 bool_t
xdr_nfsstat(XDR * xdrs,nfsstat * objp)88 xdr_nfsstat(XDR *xdrs, nfsstat *objp)
89 {
90 	return (xdr_enum(xdrs, (enum_t *)objp));
91 }
92 
93 bool_t
xdr_nfslog_sharefsres(XDR * xdrs,nfslog_sharefsres * objp)94 xdr_nfslog_sharefsres(XDR *xdrs, nfslog_sharefsres *objp)
95 {
96 	return (xdr_nfsstat(xdrs, objp));
97 }
98 
99 bool_t
xdr_nfsreadargs(XDR * xdrs,struct nfsreadargs * ra)100 xdr_nfsreadargs(XDR *xdrs, struct nfsreadargs *ra)
101 {
102 	if (xdr_fhandle(xdrs, &ra->ra_fhandle) &&
103 	    xdr_u_int(xdrs, &ra->ra_offset) &&
104 	    xdr_u_int(xdrs, &ra->ra_count) &&
105 	    xdr_u_int(xdrs, &ra->ra_totcount)) {
106 		return (TRUE);
107 	}
108 	return (FALSE);
109 }
110 
111 bool_t
xdr_nfslog_nfsreadargs(xdrs,objp)112 xdr_nfslog_nfsreadargs(xdrs, objp)
113 	register XDR *xdrs;
114 	nfslog_nfsreadargs *objp;
115 {
116 	return (xdr_nfsreadargs(xdrs, objp));
117 }
118 
119 /*
120  * Current version (2 and up) xdr function for buffer header
121  * uses 64-bit offset (relocated to an 8 byte boundary), version 1 uses 32.
122  */
123 bool_t
xdr_nfslog_buffer_header(xdrs,objp)124 xdr_nfslog_buffer_header(xdrs, objp)
125 	register XDR *xdrs;
126 	nfslog_buffer_header *objp;
127 {
128 	if (!xdr_u_int(xdrs, &objp->bh_length))
129 		return (FALSE);
130 	if (!xdr_rpcvers(xdrs, &objp->bh_version))
131 		return (FALSE);
132 	ASSERT(objp->bh_version > 1);
133 	if (!xdr_u_longlong_t(xdrs, &objp->bh_offset))
134 		return (FALSE);
135 	if (!xdr_u_int(xdrs, &objp->bh_flags))
136 		return (FALSE);
137 	return (xdr_timestruc32_t(xdrs, &objp->bh_timestamp));
138 }
139 
140 /*
141  * Hand coded xdr functions for the kernel ENCODE path
142  */
143 
144 bool_t
xdr_nfslog_request_record(XDR * xdrs,struct exportinfo * exi,struct svc_req * req,cred_t * cr,struct netbuf * pnb,unsigned int reclen,unsigned int record_id)145 xdr_nfslog_request_record(
146 	XDR *xdrs,
147 	struct exportinfo *exi,
148 	struct svc_req *req,
149 	cred_t *cr,
150 	struct netbuf *pnb,
151 	unsigned int	reclen,
152 	unsigned int	record_id)
153 {
154 	char *netid = NULL;
155 	char *prin = NULL;
156 	unsigned int flavor;
157 	timestruc32_t ts;
158 	timestruc_t now;
159 	uid_t ruid;
160 	gid_t rgid;
161 
162 	if (xdrs->x_op != XDR_ENCODE)
163 		return (FALSE);
164 
165 	/*
166 	 * First we do the encoding of the record header
167 	 */
168 	if (!xdr_u_int(xdrs, &reclen))
169 		return (FALSE);
170 	if (!xdr_u_int(xdrs, &record_id))
171 		return (FALSE);
172 	if (!xdr_rpcprog(xdrs, &req->rq_prog))
173 		return (FALSE);
174 	if (!xdr_rpcproc(xdrs, &req->rq_proc))
175 		return (FALSE);
176 	if (!xdr_rpcvers(xdrs, &req->rq_vers))
177 		return (FALSE);
178 	flavor = req->rq_cred.oa_flavor;
179 	if (!xdr_u_int(xdrs, &flavor))
180 		return (FALSE);
181 
182 	gethrestime(&now);
183 	TIMESPEC_TO_TIMESPEC32(&ts, &now);
184 	if (!xdr_timestruc32_t(xdrs, &ts))
185 		return (FALSE);
186 
187 	/* This code depends on us doing XDR_ENCODE ops only */
188 	ruid = crgetruid(cr);
189 	if (!xdr_uid_t(xdrs, &ruid))
190 		return (FALSE);
191 	rgid = crgetrgid(cr);
192 	if (!xdr_gid_t(xdrs, &rgid))
193 		return (FALSE);
194 
195 	/*
196 	 * Now encode the rest of the request record (but not args/res)
197 	 */
198 	prin = nfsl_principal_name_get(req);
199 	if (!xdr_string(xdrs, &prin, ~0))
200 		return (FALSE);
201 	if (req->rq_xprt)
202 		netid = svc_getnetid(req->rq_xprt);
203 	if (!xdr_string(xdrs, &netid, ~0))
204 		return (FALSE);
205 	if (!xdr_string(xdrs, &exi->exi_export.ex_tag, ~0))
206 		return (FALSE);
207 	return (xdr_netbuf(xdrs, pnb));
208 }
209 
210 bool_t
xdr_nfslog_sharefsargs(XDR * xdrs,struct exportinfo * objp)211 xdr_nfslog_sharefsargs(XDR *xdrs, struct exportinfo *objp)
212 {
213 
214 	if (xdrs->x_op != XDR_ENCODE)
215 		return (FALSE);
216 
217 	if (!xdr_int(xdrs, &objp->exi_export.ex_flags))
218 		return (FALSE);
219 	if (!xdr_u_int(xdrs, &objp->exi_export.ex_anon))
220 		return (FALSE);
221 	if (!xdr_string(xdrs, &objp->exi_export.ex_path, ~0))
222 		return (FALSE);
223 	return (xdr_fhandle(xdrs, &objp->exi_fh));
224 }
225 
226 bool_t
xdr_nfslog_getfhargs(XDR * xdrs,nfslog_getfhargs * objp)227 xdr_nfslog_getfhargs(XDR *xdrs, nfslog_getfhargs *objp)
228 {
229 	if (!xdr_fhandle(xdrs, &objp->gfh_fh_buf))
230 		return (FALSE);
231 	return (xdr_string(xdrs, &objp->gfh_path, ~0));
232 }
233 
234 bool_t
xdr_nfslog_drok(XDR * xdrs,struct nfsdrok * objp)235 xdr_nfslog_drok(XDR *xdrs, struct nfsdrok *objp)
236 {
237 	return (xdr_fhandle(xdrs, &objp->drok_fhandle));
238 }
239 
240 bool_t
xdr_nfslog_diropres(XDR * xdrs,struct nfsdiropres * objp)241 xdr_nfslog_diropres(XDR *xdrs, struct nfsdiropres *objp)
242 {
243 	if (!xdr_nfsstat(xdrs, &objp->dr_status))
244 		return (FALSE);
245 	switch (objp->dr_status) {
246 	case NFS_OK:
247 		if (!xdr_nfslog_drok(xdrs, &objp->dr_drok))
248 			return (FALSE);
249 		break;
250 	}
251 	return (TRUE);
252 }
253 
254 bool_t
xdr_nfslog_getattrres(XDR * xdrs,struct nfsattrstat * objp)255 xdr_nfslog_getattrres(XDR *xdrs, struct nfsattrstat *objp)
256 {
257 	return (xdr_nfsstat(xdrs, &objp->ns_status));
258 }
259 
260 bool_t
xdr_nfslog_rrok(XDR * xdrs,struct nfsrrok * objp)261 xdr_nfslog_rrok(XDR *xdrs, struct nfsrrok *objp)
262 {
263 	if (!xdr_u_int(xdrs, &objp->rrok_attr.na_size))
264 		return (FALSE);
265 	return (xdr_u_int(xdrs, &objp->rrok_count));
266 }
267 
268 bool_t
xdr_nfslog_rdresult(XDR * xdrs,struct nfsrdresult * objp)269 xdr_nfslog_rdresult(XDR *xdrs, struct nfsrdresult *objp)
270 {
271 	if (!xdr_nfsstat(xdrs, &objp->rr_status))
272 		return (FALSE);
273 	switch (objp->rr_status) {
274 	case NFS_OK:
275 		if (!xdr_nfslog_rrok(xdrs, &objp->rr_u.rr_ok_u))
276 			return (FALSE);
277 		break;
278 	}
279 	return (TRUE);
280 }
281 
282 bool_t
xdr_nfslog_writeargs(XDR * xdrs,struct nfswriteargs * objp)283 xdr_nfslog_writeargs(XDR *xdrs, struct nfswriteargs *objp)
284 {
285 	if (!xdr_fhandle(xdrs, &objp->wa_args->otw_wa_fhandle))
286 		return (FALSE);
287 	if (!xdr_u_int(xdrs, &objp->wa_args->otw_wa_begoff))
288 		return (FALSE);
289 	if (!xdr_u_int(xdrs, &objp->wa_args->otw_wa_offset))
290 		return (FALSE);
291 	if (!xdr_u_int(xdrs, &objp->wa_args->otw_wa_totcount))
292 		return (FALSE);
293 	return (xdr_u_int(xdrs, &objp->wa_count));
294 }
295 
296 bool_t
xdr_nfslog_writeresult(XDR * xdrs,struct nfsattrstat * objp)297 xdr_nfslog_writeresult(XDR *xdrs, struct nfsattrstat *objp)
298 {
299 	if (!xdr_nfsstat(xdrs, &objp->ns_status))
300 		return (FALSE);
301 	switch (objp->ns_status) {
302 	case NFS_OK:
303 		if (!xdr_u_int(xdrs, &objp->ns_u.ns_attr_u.na_size))
304 			return (FALSE);
305 		break;
306 	}
307 	return (TRUE);
308 }
309 
310 bool_t
xdr_nfslog_diropargs(XDR * xdrs,struct nfsdiropargs * objp)311 xdr_nfslog_diropargs(XDR *xdrs, struct nfsdiropargs *objp)
312 {
313 	if (!xdr_fhandle(xdrs, objp->da_fhandle))
314 		return (FALSE);
315 	return (xdr_string(xdrs, &objp->da_name, ~0));
316 }
317 
318 bool_t
xdr_nfslog_sattr(XDR * xdrs,struct nfssattr * objp)319 xdr_nfslog_sattr(XDR *xdrs, struct nfssattr *objp)
320 {
321 	if (!xdr_u_int(xdrs, &objp->sa_mode))
322 		return (FALSE);
323 	if (!xdr_u_int(xdrs, &objp->sa_uid))
324 		return (FALSE);
325 	if (!xdr_u_int(xdrs, &objp->sa_gid))
326 		return (FALSE);
327 	if (!xdr_u_int(xdrs, &objp->sa_size))
328 		return (FALSE);
329 	if (!xdr_nfs2_timeval(xdrs, (nfs2_timeval *)&objp->sa_atime))
330 		return (FALSE);
331 	return (xdr_nfs2_timeval(xdrs, (nfs2_timeval *)&objp->sa_mtime));
332 }
333 
334 bool_t
xdr_nfslog_createargs(XDR * xdrs,struct nfscreatargs * objp)335 xdr_nfslog_createargs(XDR *xdrs, struct nfscreatargs *objp)
336 {
337 	if (!xdr_nfslog_sattr(xdrs, objp->ca_sa))
338 		return (FALSE);
339 	return (xdr_nfslog_diropargs(xdrs, &objp->ca_da));
340 }
341 
342 bool_t
xdr_nfslog_setattrargs(XDR * xdrs,struct nfssaargs * objp)343 xdr_nfslog_setattrargs(XDR *xdrs, struct nfssaargs *objp)
344 {
345 	if (!xdr_fhandle(xdrs, &objp->saa_fh))
346 		return (FALSE);
347 	return (xdr_nfslog_sattr(xdrs, &objp->saa_sa));
348 }
349 
350 bool_t
xdr_nfslog_rdlnres(XDR * xdrs,struct nfsrdlnres * objp)351 xdr_nfslog_rdlnres(XDR *xdrs, struct nfsrdlnres *objp)
352 {
353 	caddr_t	lnres = NULL;
354 	int count;
355 
356 	if (!xdr_nfsstat(xdrs, &objp->rl_status))
357 		return (FALSE);
358 	switch (objp->rl_status) {
359 	case NFS_OK:
360 		if ((count = objp->rl_u.rl_srok_u.srok_count) != 0) {
361 			/*
362 			 * allocate extra element for terminating NULL
363 			 */
364 			lnres = kmem_alloc(count + 1, KM_SLEEP);
365 			bcopy(objp->rl_u.rl_srok_u.srok_data, lnres, count);
366 			lnres[count] = '\0';
367 		}
368 		if (!xdr_string(xdrs, &lnres, ~0)) {
369 			if (lnres != NULL)
370 				kmem_free(lnres, count + 1);
371 			return (FALSE);
372 		}
373 		if (lnres != NULL)
374 			kmem_free(lnres, count + 1);
375 		break;
376 	}
377 	return (TRUE);
378 }
379 
380 bool_t
xdr_nfslog_rnmargs(XDR * xdrs,struct nfsrnmargs * objp)381 xdr_nfslog_rnmargs(XDR *xdrs, struct nfsrnmargs *objp)
382 {
383 	if (!xdr_nfslog_diropargs(xdrs, &objp->rna_from))
384 		return (FALSE);
385 	return (xdr_nfslog_diropargs(xdrs, &objp->rna_to));
386 }
387 
388 bool_t
xdr_nfslog_linkargs(XDR * xdrs,struct nfslinkargs * objp)389 xdr_nfslog_linkargs(XDR *xdrs, struct nfslinkargs *objp)
390 {
391 	if (!xdr_fhandle(xdrs, objp->la_from))
392 		return (FALSE);
393 	return (xdr_nfslog_diropargs(xdrs, &objp->la_to));
394 }
395 
396 bool_t
xdr_nfslog_symlinkargs(XDR * xdrs,struct nfsslargs * objp)397 xdr_nfslog_symlinkargs(XDR *xdrs, struct nfsslargs *objp)
398 {
399 	if (!xdr_nfslog_diropargs(xdrs, &objp->sla_from))
400 		return (FALSE);
401 	if (!xdr_string(xdrs, &objp->sla_tnm, ~0))
402 		return (FALSE);
403 	return (xdr_nfslog_sattr(xdrs, objp->sla_sa));
404 }
405 
406 bool_t
xdr_nfslog_statfs(XDR * xdrs,struct nfsstatfs * objp)407 xdr_nfslog_statfs(XDR *xdrs, struct nfsstatfs *objp)
408 {
409 	return (xdr_nfsstat(xdrs, &objp->fs_status));
410 }
411 
412 bool_t
xdr_nfslog_rddirargs(XDR * xdrs,struct nfsrddirargs * objp)413 xdr_nfslog_rddirargs(XDR *xdrs, struct nfsrddirargs *objp)
414 {
415 	if (!xdr_fhandle(xdrs, &objp->rda_fh))
416 		return (FALSE);
417 	if (!xdr_u_int(xdrs, &objp->rda_offset))
418 		return (FALSE);
419 	return (xdr_u_int(xdrs, &objp->rda_count));
420 }
421 
422 bool_t
xdr_nfslog_rdok(XDR * xdrs,struct nfsrdok * objp)423 xdr_nfslog_rdok(XDR *xdrs, struct nfsrdok *objp)
424 {
425 	if (!xdr_u_int(xdrs, &objp->rdok_offset))
426 		return (FALSE);
427 	if (!xdr_u_int(xdrs, &objp->rdok_size))
428 		return (FALSE);
429 	return (xdr_bool(xdrs, &objp->rdok_eof));
430 }
431 
432 bool_t
xdr_nfslog_rddirres(XDR * xdrs,struct nfsrddirres * objp)433 xdr_nfslog_rddirres(XDR *xdrs, struct nfsrddirres *objp)
434 {
435 	if (!xdr_nfsstat(xdrs, &objp->rd_status))
436 		return (FALSE);
437 	switch (objp->rd_status) {
438 	case NFS_OK:
439 		if (!xdr_nfslog_rdok(xdrs, &objp->rd_u.rd_rdok_u))
440 			return (FALSE);
441 		break;
442 	}
443 	return (TRUE);
444 }
445 
446 bool_t
xdr_nfslog_diropargs3(XDR * xdrs,diropargs3 * objp)447 xdr_nfslog_diropargs3(XDR *xdrs, diropargs3 *objp)
448 {
449 	char *name;
450 
451 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->dir))
452 		return (FALSE);
453 	if (objp->name != nfs3nametoolong)
454 		name = objp->name;
455 	else {
456 		/*
457 		 * The name is not defined, set it to the
458 		 * zero length string.
459 		 */
460 		name = NULL;
461 	}
462 	return (xdr_string(xdrs, &name, ~0));
463 }
464 
465 bool_t
xdr_nfslog_LOOKUP3res(XDR * xdrs,LOOKUP3res * objp)466 xdr_nfslog_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
467 {
468 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
469 		return (FALSE);
470 	switch (objp->status) {
471 	case NFS3_OK:
472 		if (!xdr_nfslog_nfs_fh3(xdrs, &objp->res_u.ok.object))
473 			return (FALSE);
474 		break;
475 	}
476 	return (TRUE);
477 }
478 
479 bool_t
xdr_set_size3(XDR * xdrs,set_size3 * objp)480 xdr_set_size3(XDR *xdrs, set_size3 *objp)
481 {
482 	if (!xdr_bool(xdrs, &objp->set_it))
483 		return (FALSE);
484 	switch (objp->set_it) {
485 	case TRUE:
486 		if (!xdr_uint64(xdrs, &objp->size))
487 			return (FALSE);
488 		break;
489 	}
490 	return (TRUE);
491 }
492 
493 bool_t
xdr_nfslog_createhow3(XDR * xdrs,createhow3 * objp)494 xdr_nfslog_createhow3(XDR *xdrs, createhow3 *objp)
495 {
496 	if (!xdr_enum(xdrs, (enum_t *)&objp->mode))
497 		return (FALSE);
498 	switch (objp->mode) {
499 	case UNCHECKED:
500 	case GUARDED:
501 		if (!xdr_set_size3(xdrs,
502 			&objp->createhow3_u.obj_attributes.size))
503 			return (FALSE);
504 		break;
505 	case EXCLUSIVE:
506 		break;
507 	default:
508 		return (FALSE);
509 	}
510 	return (TRUE);
511 }
512 
513 bool_t
xdr_nfslog_CREATE3args(XDR * xdrs,CREATE3args * objp)514 xdr_nfslog_CREATE3args(XDR *xdrs, CREATE3args *objp)
515 {
516 	if (!xdr_nfslog_diropargs3(xdrs, &objp->where))
517 		return (FALSE);
518 	return (xdr_nfslog_createhow3(xdrs, &objp->how));
519 }
520 
521 bool_t
xdr_nfslog_CREATE3resok(XDR * xdrs,CREATE3resok * objp)522 xdr_nfslog_CREATE3resok(XDR *xdrs, CREATE3resok *objp)
523 {
524 	return (xdr_post_op_fh3(xdrs, &objp->obj));
525 }
526 
527 bool_t
xdr_nfslog_CREATE3res(XDR * xdrs,CREATE3res * objp)528 xdr_nfslog_CREATE3res(XDR *xdrs, CREATE3res *objp)
529 {
530 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
531 		return (FALSE);
532 	switch (objp->status) {
533 	case NFS3_OK:
534 		if (!xdr_nfslog_CREATE3resok(xdrs, &objp->res_u.ok))
535 			return (FALSE);
536 		break;
537 	}
538 	return (TRUE);
539 }
540 
541 bool_t
xdr_nfslog_GETATTR3res(XDR * xdrs,GETATTR3res * objp)542 xdr_nfslog_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
543 {
544 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
545 }
546 
547 bool_t
xdr_nfslog_ACCESS3args(XDR * xdrs,ACCESS3args * objp)548 xdr_nfslog_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
549 {
550 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->object));
551 }
552 
553 bool_t
xdr_nfslog_ACCESS3res(XDR * xdrs,ACCESS3res * objp)554 xdr_nfslog_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
555 {
556 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
557 }
558 
559 bool_t
xdr_nfslog_SETATTR3args(XDR * xdrs,SETATTR3args * objp)560 xdr_nfslog_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
561 {
562 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->object))
563 		return (FALSE);
564 	return (xdr_set_size3(xdrs, &objp->new_attributes.size));
565 }
566 
567 bool_t
xdr_nfslog_SETATTR3res(XDR * xdrs,SETATTR3res * objp)568 xdr_nfslog_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
569 {
570 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
571 }
572 
573 bool_t
xdr_nfslog_READLINK3res(XDR * xdrs,READLINK3res * objp)574 xdr_nfslog_READLINK3res(XDR *xdrs, READLINK3res *objp)
575 {
576 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
577 		return (FALSE);
578 	switch (objp->status) {
579 	case NFS3_OK:
580 		if (!xdr_string(xdrs, &objp->res_u.ok.data, ~0))
581 			return (FALSE);
582 		break;
583 	}
584 	return (TRUE);
585 }
586 
587 bool_t
xdr_nfslog_READ3args(XDR * xdrs,READ3args * objp)588 xdr_nfslog_READ3args(XDR *xdrs, READ3args *objp)
589 {
590 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
591 		return (FALSE);
592 	if (!xdr_uint64(xdrs, &objp->offset))
593 		return (FALSE);
594 	return (xdr_uint32(xdrs, &objp->count));
595 }
596 
597 bool_t
xdr_nfslog_READ3resok(XDR * xdrs,READ3resok * objp)598 xdr_nfslog_READ3resok(XDR *xdrs, READ3resok *objp)
599 {
600 	if (!xdr_uint64(xdrs, &objp->file_attributes.attr.size))
601 		return (FALSE);
602 	if (!xdr_uint32(xdrs, &objp->count))
603 		return (FALSE);
604 	if (!xdr_bool(xdrs, &objp->eof))
605 		return (FALSE);
606 	return (xdr_u_int(xdrs, &objp->size));
607 }
608 
609 bool_t
xdr_nfslog_READ3res(XDR * xdrs,READ3res * objp)610 xdr_nfslog_READ3res(XDR *xdrs, READ3res *objp)
611 {
612 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
613 		return (FALSE);
614 	switch (objp->status) {
615 	case NFS3_OK:
616 		if (!xdr_nfslog_READ3resok(xdrs, &objp->res_u.ok))
617 			return (FALSE);
618 		break;
619 	}
620 	return (TRUE);
621 }
622 
623 bool_t
xdr_nfslog_WRITE3args(XDR * xdrs,WRITE3args * objp)624 xdr_nfslog_WRITE3args(XDR *xdrs, WRITE3args *objp)
625 {
626 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
627 		return (FALSE);
628 	if (!xdr_uint64(xdrs, &objp->offset))
629 		return (FALSE);
630 	if (!xdr_uint32(xdrs, &objp->count))
631 		return (FALSE);
632 	return (xdr_enum(xdrs, (enum_t *)&objp->stable));
633 }
634 
635 bool_t
xdr_nfslog_WRITE3resok(XDR * xdrs,WRITE3resok * objp)636 xdr_nfslog_WRITE3resok(XDR *xdrs, WRITE3resok *objp)
637 {
638 	if (!xdr_uint64(xdrs, &objp->file_wcc.after.attr.size))
639 		return (FALSE);
640 	if (!xdr_uint32(xdrs, &objp->count))
641 		return (FALSE);
642 	return (xdr_enum(xdrs, (enum_t *)&objp->committed));
643 }
644 
645 bool_t
xdr_nfslog_WRITE3res(XDR * xdrs,WRITE3res * objp)646 xdr_nfslog_WRITE3res(XDR *xdrs, WRITE3res *objp)
647 {
648 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
649 		return (FALSE);
650 	switch (objp->status) {
651 	case NFS3_OK:
652 		if (!xdr_nfslog_WRITE3resok(xdrs, &objp->res_u.ok))
653 			return (FALSE);
654 		break;
655 	}
656 	return (TRUE);
657 }
658 
659 bool_t
xdr_nfslog_MKDIR3args(XDR * xdrs,MKDIR3args * objp)660 xdr_nfslog_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
661 {
662 	return (xdr_nfslog_diropargs3(xdrs, &objp->where));
663 }
664 
665 bool_t
xdr_nfslog_MKDIR3res(XDR * xdrs,MKDIR3res * objp)666 xdr_nfslog_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
667 {
668 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
669 		return (FALSE);
670 	switch (objp->status) {
671 	case NFS3_OK:
672 		if (!xdr_post_op_fh3(xdrs, &objp->res_u.ok.obj))
673 			return (FALSE);
674 		break;
675 	}
676 	return (TRUE);
677 }
678 
679 bool_t
xdr_nfslog_SYMLINK3args(XDR * xdrs,SYMLINK3args * objp)680 xdr_nfslog_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
681 {
682 	if (!xdr_nfslog_diropargs3(xdrs, &objp->where))
683 		return (FALSE);
684 	return (xdr_string(xdrs, &objp->symlink.symlink_data, ~0));
685 }
686 
687 bool_t
xdr_nfslog_SYMLINK3res(XDR * xdrs,SYMLINK3res * objp)688 xdr_nfslog_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
689 {
690 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
691 		return (FALSE);
692 	switch (objp->status) {
693 	case NFS3_OK:
694 		if (!xdr_post_op_fh3(xdrs, &objp->res_u.ok.obj))
695 			return (FALSE);
696 		break;
697 	}
698 	return (TRUE);
699 }
700 
701 bool_t
xdr_nfslog_MKNOD3args(XDR * xdrs,MKNOD3args * objp)702 xdr_nfslog_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
703 {
704 	if (!xdr_nfslog_diropargs3(xdrs, &objp->where))
705 		return (FALSE);
706 	return (xdr_enum(xdrs, (enum_t *)&objp->what.type));
707 }
708 
709 bool_t
xdr_nfslog_MKNOD3res(XDR * xdrs,MKNOD3res * objp)710 xdr_nfslog_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
711 {
712 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
713 		return (FALSE);
714 	switch (objp->status) {
715 	case NFS3_OK:
716 		if (!xdr_post_op_fh3(xdrs, &objp->res_u.ok.obj))
717 			return (FALSE);
718 		break;
719 	}
720 	return (TRUE);
721 }
722 
723 bool_t
xdr_nfslog_REMOVE3args(XDR * xdrs,REMOVE3args * objp)724 xdr_nfslog_REMOVE3args(XDR *xdrs, REMOVE3args *objp)
725 {
726 	return (xdr_nfslog_diropargs3(xdrs, &objp->object));
727 }
728 
729 bool_t
xdr_nfslog_REMOVE3res(XDR * xdrs,REMOVE3res * objp)730 xdr_nfslog_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
731 {
732 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
733 }
734 
735 bool_t
xdr_nfslog_RMDIR3args(XDR * xdrs,RMDIR3args * objp)736 xdr_nfslog_RMDIR3args(XDR *xdrs, RMDIR3args *objp)
737 {
738 	return (xdr_nfslog_diropargs3(xdrs, &objp->object));
739 }
740 
741 bool_t
xdr_nfslog_RMDIR3res(XDR * xdrs,RMDIR3res * objp)742 xdr_nfslog_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
743 {
744 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
745 }
746 
747 bool_t
xdr_nfslog_RENAME3args(XDR * xdrs,RENAME3args * objp)748 xdr_nfslog_RENAME3args(XDR *xdrs, RENAME3args *objp)
749 {
750 	if (!xdr_nfslog_diropargs3(xdrs, &objp->from))
751 		return (FALSE);
752 	return (xdr_nfslog_diropargs3(xdrs, &objp->to));
753 }
754 
755 bool_t
xdr_nfslog_RENAME3res(XDR * xdrs,RENAME3res * objp)756 xdr_nfslog_RENAME3res(XDR *xdrs, RENAME3res *objp)
757 {
758 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
759 }
760 
761 bool_t
xdr_nfslog_LINK3args(XDR * xdrs,LINK3args * objp)762 xdr_nfslog_LINK3args(XDR *xdrs, LINK3args *objp)
763 {
764 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
765 		return (FALSE);
766 	return (xdr_nfslog_diropargs3(xdrs, &objp->link));
767 }
768 
769 bool_t
xdr_nfslog_LINK3res(XDR * xdrs,LINK3res * objp)770 xdr_nfslog_LINK3res(XDR *xdrs, LINK3res *objp)
771 {
772 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
773 }
774 
775 bool_t
xdr_nfslog_READDIR3args(XDR * xdrs,READDIR3args * objp)776 xdr_nfslog_READDIR3args(XDR *xdrs, READDIR3args *objp)
777 {
778 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->dir));
779 }
780 
781 bool_t
xdr_nfslog_READDIR3res(XDR * xdrs,READDIR3res * objp)782 xdr_nfslog_READDIR3res(XDR *xdrs, READDIR3res *objp)
783 {
784 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
785 }
786 
787 bool_t
xdr_nfslog_READDIRPLUS3args(XDR * xdrs,READDIRPLUS3args * objp)788 xdr_nfslog_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
789 {
790 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->dir))
791 		return (FALSE);
792 	if (!xdr_uint32(xdrs, &objp->dircount))
793 		return (FALSE);
794 	return (xdr_uint32(xdrs, &objp->maxcount));
795 }
796 
797 #ifdef	nextdp
798 #undef	nextdp
799 #endif
800 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
801 
802 bool_t
xdr_nfslog_READDIRPLUS3resok(XDR * xdrs,READDIRPLUS3resok * objp)803 xdr_nfslog_READDIRPLUS3resok(XDR *xdrs, READDIRPLUS3resok *objp)
804 {
805 	struct dirent64 *dp;
806 	bool_t true = TRUE;
807 	bool_t false = FALSE;
808 	int nents;
809 	char *name;
810 	entryplus3_info *infop;
811 
812 	dp = (struct dirent64 *)objp->reply.entries;
813 	nents = objp->size;
814 	infop = objp->infop;
815 	while (nents > 0) {
816 		if (dp->d_reclen == 0)
817 			return (FALSE);
818 		if (dp->d_ino == 0) {
819 			dp = nextdp(dp);
820 			infop++;
821 			nents--;
822 			continue;
823 		}
824 		name = dp->d_name;
825 
826 		if (!xdr_bool(xdrs, &true) ||
827 		    !xdr_post_op_fh3(xdrs, &infop->fh) ||
828 		    !xdr_string(xdrs, &name, ~0)) {
829 			return (FALSE);
830 		}
831 		dp = nextdp(dp);
832 		infop++;
833 		nents--;
834 	}
835 	if (!xdr_bool(xdrs, &false))
836 		return (FALSE);
837 
838 	return (xdr_bool(xdrs, &objp->reply.eof));
839 }
840 
841 bool_t
xdr_nfslog_READDIRPLUS3res(XDR * xdrs,READDIRPLUS3res * objp)842 xdr_nfslog_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
843 {
844 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
845 		return (FALSE);
846 	switch (objp->status) {
847 	case NFS3_OK:
848 		if (!xdr_nfslog_READDIRPLUS3resok(xdrs, &objp->res_u.ok))
849 			return (FALSE);
850 		break;
851 	}
852 	return (TRUE);
853 }
854 
855 bool_t
xdr_nfslog_FSSTAT3args(XDR * xdrs,FSSTAT3args * objp)856 xdr_nfslog_FSSTAT3args(XDR *xdrs, FSSTAT3args *objp)
857 {
858 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->fsroot));
859 }
860 
861 bool_t
xdr_nfslog_FSSTAT3res(XDR * xdrs,FSSTAT3res * objp)862 xdr_nfslog_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
863 {
864 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
865 }
866 
867 bool_t
xdr_nfslog_FSINFO3args(XDR * xdrs,FSINFO3args * objp)868 xdr_nfslog_FSINFO3args(XDR *xdrs, FSINFO3args *objp)
869 {
870 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->fsroot));
871 }
872 
873 bool_t
xdr_nfslog_FSINFO3res(XDR * xdrs,FSINFO3res * objp)874 xdr_nfslog_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
875 {
876 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
877 }
878 
879 bool_t
xdr_nfslog_PATHCONF3args(XDR * xdrs,PATHCONF3args * objp)880 xdr_nfslog_PATHCONF3args(XDR *xdrs, PATHCONF3args *objp)
881 {
882 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->object));
883 }
884 
885 bool_t
xdr_nfslog_PATHCONF3res(XDR * xdrs,PATHCONF3res * objp)886 xdr_nfslog_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
887 {
888 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
889 }
890 
891 bool_t
xdr_nfslog_COMMIT3args(XDR * xdrs,COMMIT3args * objp)892 xdr_nfslog_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
893 {
894 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
895 		return (FALSE);
896 	if (!xdr_uint64(xdrs, &objp->offset))
897 		return (FALSE);
898 	return (xdr_uint32(xdrs, &objp->count));
899 }
900 
901 bool_t
xdr_nfslog_COMMIT3res(XDR * xdrs,COMMIT3res * objp)902 xdr_nfslog_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
903 {
904 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
905 }
906 
907 bool_t
xdr_nfslog_nfs_fh3(XDR * xdrs,nfs_fh3 * objp)908 xdr_nfslog_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
909 {
910 	nfs_fh3 fh;
911 
912 	if (objp->fh3_len > NFS_FHMAXDATA || objp->fh3_xlen > NFS_FHMAXDATA) {
913 		fh = *objp;
914 		fh.fh3_len = NFS_FHMAXDATA;
915 		fh.fh3_xlen = NFS_FHMAXDATA;
916 		fh.fh3_length = NFS3_OLDFHSIZE;
917 		return (xdr_nfs_fh3_server(xdrs, &fh));
918 	}
919 	return (xdr_nfs_fh3_server(xdrs, objp));
920 }
921