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 *
  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
  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
  88 xdr_nfsstat(XDR *xdrs, nfsstat *objp)
  89 {
  90         return (xdr_enum(xdrs, (enum_t *)objp));
  91 }
  92 
  93 bool_t
  94 xdr_nfslog_sharefsres(XDR *xdrs, nfslog_sharefsres *objp)
  95 {
  96         return (xdr_nfsstat(xdrs, objp));
  97 }
  98 
  99 bool_t
 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
 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
 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
 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
 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
 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
 235 xdr_nfslog_drok(XDR *xdrs, struct nfsdrok *objp)
 236 {
 237         return (xdr_fhandle(xdrs, &objp->drok_fhandle));
 238 }
 239 
 240 bool_t
 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
 255 xdr_nfslog_getattrres(XDR *xdrs, struct nfsattrstat *objp)
 256 {
 257         return (xdr_nfsstat(xdrs, &objp->ns_status));
 258 }
 259 
 260 bool_t
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 407 xdr_nfslog_statfs(XDR *xdrs, struct nfsstatfs *objp)
 408 {
 409         return (xdr_nfsstat(xdrs, &objp->fs_status));
 410 }
 411 
 412 bool_t
 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
 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
 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
 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
 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
 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
 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
 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
 522 xdr_nfslog_CREATE3resok(XDR *xdrs, CREATE3resok *objp)
 523 {
 524         return (xdr_post_op_fh3(xdrs, &objp->obj));
 525 }
 526 
 527 bool_t
 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
 542 xdr_nfslog_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
 543 {
 544         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 545 }
 546 
 547 bool_t
 548 xdr_nfslog_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
 549 {
 550         return (xdr_nfslog_nfs_fh3(xdrs, &objp->object));
 551 }
 552 
 553 bool_t
 554 xdr_nfslog_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
 555 {
 556         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 557 }
 558 
 559 bool_t
 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
 568 xdr_nfslog_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
 569 {
 570         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 571 }
 572 
 573 bool_t
 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
 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
 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
 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
 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
 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
 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
 660 xdr_nfslog_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
 661 {
 662         return (xdr_nfslog_diropargs3(xdrs, &objp->where));
 663 }
 664 
 665 bool_t
 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
 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
 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
 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
 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
 724 xdr_nfslog_REMOVE3args(XDR *xdrs, REMOVE3args *objp)
 725 {
 726         return (xdr_nfslog_diropargs3(xdrs, &objp->object));
 727 }
 728 
 729 bool_t
 730 xdr_nfslog_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
 731 {
 732         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 733 }
 734 
 735 bool_t
 736 xdr_nfslog_RMDIR3args(XDR *xdrs, RMDIR3args *objp)
 737 {
 738         return (xdr_nfslog_diropargs3(xdrs, &objp->object));
 739 }
 740 
 741 bool_t
 742 xdr_nfslog_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
 743 {
 744         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 745 }
 746 
 747 bool_t
 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
 756 xdr_nfslog_RENAME3res(XDR *xdrs, RENAME3res *objp)
 757 {
 758         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 759 }
 760 
 761 bool_t
 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
 770 xdr_nfslog_LINK3res(XDR *xdrs, LINK3res *objp)
 771 {
 772         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 773 }
 774 
 775 bool_t
 776 xdr_nfslog_READDIR3args(XDR *xdrs, READDIR3args *objp)
 777 {
 778         return (xdr_nfslog_nfs_fh3(xdrs, &objp->dir));
 779 }
 780 
 781 bool_t
 782 xdr_nfslog_READDIR3res(XDR *xdrs, READDIR3res *objp)
 783 {
 784         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 785 }
 786 
 787 bool_t
 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
 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
 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
 856 xdr_nfslog_FSSTAT3args(XDR *xdrs, FSSTAT3args *objp)
 857 {
 858         return (xdr_nfslog_nfs_fh3(xdrs, &objp->fsroot));
 859 }
 860 
 861 bool_t
 862 xdr_nfslog_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
 863 {
 864         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 865 }
 866 
 867 bool_t
 868 xdr_nfslog_FSINFO3args(XDR *xdrs, FSINFO3args *objp)
 869 {
 870         return (xdr_nfslog_nfs_fh3(xdrs, &objp->fsroot));
 871 }
 872 
 873 bool_t
 874 xdr_nfslog_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
 875 {
 876         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 877 }
 878 
 879 bool_t
 880 xdr_nfslog_PATHCONF3args(XDR *xdrs, PATHCONF3args *objp)
 881 {
 882         return (xdr_nfslog_nfs_fh3(xdrs, &objp->object));
 883 }
 884 
 885 bool_t
 886 xdr_nfslog_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
 887 {
 888         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 889 }
 890 
 891 bool_t
 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
 902 xdr_nfslog_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
 903 {
 904         return (xdr_enum(xdrs, (enum_t *)&objp->status));
 905 }
 906 
 907 bool_t
 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 }