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