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