394         struct vattr *vap;
 395         struct vattr va;
 396         struct vattr *dvap;
 397         struct vattr dva;
 398         nfs_fh3 *fhp;
 399         struct sec_ol sec = {0, 0};
 400         bool_t publicfh_flag = FALSE, auth_weak = FALSE;
 401         struct sockaddr *ca;
 402         char *name = NULL;
 403 
 404         dvap = NULL;
 405 
 406         if (exi != NULL)
 407                 exi_hold(exi);
 408 
 409         /*
 410          * Allow lookups from the root - the default
 411          * location of the public filehandle.
 412          */
 413         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 414                 dvp = ZONE_ROOTVP();
 415                 VN_HOLD(dvp);
 416 
 417                 DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
 418                     cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 419                     LOOKUP3args *, args);
 420         } else {
 421                 dvp = nfs3_fhtovp(&args->what.dir, exi);
 422 
 423                 DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
 424                     cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 425                     LOOKUP3args *, args);
 426 
 427                 if (dvp == NULL) {
 428                         error = ESTALE;
 429                         goto out;
 430                 }
 431         }
 432 
 433         dva.va_mask = AT_ALL;
 434         dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;
 435 
 436         if (args->what.name == nfs3nametoolong) {
 437                 resp->status = NFS3ERR_NAMETOOLONG;
 438                 goto out1;
 439         }
 440 
 441         if (args->what.name == NULL || *(args->what.name) == '\0') {
 442                 resp->status = NFS3ERR_ACCES;
 443                 goto out1;
 444         }
 445 
 446         fhp = &args->what.dir;
 447         if (strcmp(args->what.name, "..") == 0 &&
 448             EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 449                 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 450                     (dvp->v_flag & VROOT)) {
 451                         /*
 452                          * special case for ".." and 'nohide'exported root
 453                          */
 454                         if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 455                                 resp->status = NFS3ERR_ACCES;
 456                                 goto out1;
 457                         }
 458                 } else {
 459                         resp->status = NFS3ERR_NOENT;
 460                         goto out1;
 461                 }
 462         }
 463 
 464         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 465         name = nfscmd_convname(ca, exi, args->what.name,
 466             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
 467 
 468         if (name == NULL) {
 469                 resp->status = NFS3ERR_ACCES;
 470                 goto out1;
 471         }
 472 
 473         /*
 474          * If the public filehandle is used then allow
 475          * a multi-component lookup
 476          */
 477         if (PUBLIC_FH3(&args->what.dir)) {
 478                 publicfh_flag = TRUE;
 479 
 480                 exi_rele(exi);
 481 
 482                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 483                     &exi, &sec);
 484 
 485                 /*
 486                  * Since WebNFS may bypass MOUNT, we need to ensure this
 487                  * request didn't come from an unlabeled admin_low client.
 488                  */
 489                 if (is_system_labeled() && error == 0) {
 490                         int             addr_type;
 491                         void            *ipaddr;
 492                         tsol_tpc_t      *tp;
 493 
 494                         if (ca->sa_family == AF_INET) {
 495                                 addr_type = IPV4_VERSION;
 496                                 ipaddr = &((struct sockaddr_in *)ca)->sin_addr;
 497                         } else if (ca->sa_family == AF_INET6) {
 498                                 addr_type = IPV6_VERSION;
 499                                 ipaddr = &((struct sockaddr_in6 *)
 500                                     ca)->sin6_addr;
 
 544 
 545         if (error)
 546                 goto out;
 547 
 548         if (sec.sec_flags & SEC_QUERY) {
 549                 error = makefh3_ol(&resp->resok.object, exi, sec.sec_index);
 550         } else {
 551                 error = makefh3(&resp->resok.object, vp, exi);
 552                 if (!error && publicfh_flag && !chk_clnt_sec(exi, req))
 553                         auth_weak = TRUE;
 554         }
 555 
 556         if (error) {
 557                 VN_RELE(vp);
 558                 goto out;
 559         }
 560 
 561         va.va_mask = AT_ALL;
 562         vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 563 
 564         exi_rele(exi);
 565         VN_RELE(vp);
 566 
 567         resp->status = NFS3_OK;
 568         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 569         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 570 
 571         /*
 572          * If it's public fh, no 0x81, and client's flavor is
 573          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 574          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 575          */
 576         if (auth_weak)
 577                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 578 
 579         DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
 580             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 581             LOOKUP3res *, resp);
 582         VN_RELE(dvp);
 583 
 584         return;
 585 
 586 out:
 587         if (curthread->t_flag & T_WOULDBLOCK) {
 588                 curthread->t_flag &= ~T_WOULDBLOCK;
 589                 resp->status = NFS3ERR_JUKEBOX;
 590         } else
 591                 resp->status = puterrno3(error);
 592 out1:
 593         DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
 594             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 595             LOOKUP3res *, resp);
 596 
 597         if (exi != NULL)
 598                 exi_rele(exi);
 599 
 600         if (dvp != NULL)
 601                 VN_RELE(dvp);
 602         vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
 
1316         mblk_t *m;
1317         struct iovec *iovp;
1318         int iovcnt;
1319         int ioflag;
1320         cred_t *savecred;
1321         int in_crit = 0;
1322         int rwlock_ret = -1;
1323         caller_context_t ct;
1324 
1325         vp = nfs3_fhtovp(&args->file, exi);
1326 
1327         DTRACE_NFSV3_5(op__write__start, struct svc_req *, req,
1328             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
1329             WRITE3args *, args);
1330 
1331         if (vp == NULL) {
1332                 error = ESTALE;
1333                 goto err;
1334         }
1335 
1336         ns = nfs3_get_srv();
1337         if (is_system_labeled()) {
1338                 bslabel_t *clabel = req->rq_label;
1339 
1340                 ASSERT(clabel != NULL);
1341                 DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
1342                     "got client label from request(1)", struct svc_req *, req);
1343 
1344                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
1345                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
1346                             exi)) {
1347                                 resp->status = NFS3ERR_ACCES;
1348                                 goto err1;
1349                         }
1350                 }
1351         }
1352 
1353         ct.cc_sysid = 0;
1354         ct.cc_pid = 0;
1355         ct.cc_caller_id = nfs3_srv_caller_id;
1356         ct.cc_flags = CC_DONTBLOCK;
 
2654                     "got client label from request(1)", struct svc_req *, req);
2655 
2656                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2657                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
2658                             exi)) {
2659                                 resp->status = NFS3ERR_ACCES;
2660                                 goto err1;
2661                         }
2662                 }
2663         }
2664 
2665         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2666         name = nfscmd_convname(ca, exi, args->object.name,
2667             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2668 
2669         if (name == NULL) {
2670                 resp->status = NFS3ERR_INVAL;
2671                 goto err1;
2672         }
2673 
2674         error = VOP_RMDIR(vp, name, ZONE_ROOTVP(), cr, NULL, 0);
2675 
2676         if (name != args->object.name)
2677                 kmem_free(name, MAXPATHLEN + 1);
2678 
2679         ava.va_mask = AT_ALL;
2680         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2681 
2682         /*
2683          * Force modified data and metadata out to stable storage.
2684          */
2685         (void) VOP_FSYNC(vp, 0, cr, NULL);
2686 
2687         if (error) {
2688                 /*
2689                  * System V defines rmdir to return EEXIST, not ENOTEMPTY,
2690                  * if the directory is not empty.  A System V NFS server
2691                  * needs to map NFS3ERR_EXIST to NFS3ERR_NOTEMPTY to transmit
2692                  * over the wire.
2693                  */
 
4116         vnode_t *vp;
4117         struct vattr *bvap;
4118         struct vattr bva;
4119         struct vattr *avap;
4120         struct vattr ava;
4121 
4122         bvap = NULL;
4123         avap = NULL;
4124 
4125         vp = nfs3_fhtovp(&args->file, exi);
4126 
4127         DTRACE_NFSV3_5(op__commit__start, struct svc_req *, req,
4128             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
4129             COMMIT3args *, args);
4130 
4131         if (vp == NULL) {
4132                 error = ESTALE;
4133                 goto out;
4134         }
4135 
4136         ns = nfs3_get_srv();
4137         bva.va_mask = AT_ALL;
4138         error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4139 
4140         /*
4141          * If we can't get the attributes, then we can't do the
4142          * right access checking.  So, we'll fail the request.
4143          */
4144         if (error)
4145                 goto out;
4146 
4147         bvap = &bva;
4148 
4149         if (rdonly(ro, vp)) {
4150                 resp->status = NFS3ERR_ROFS;
4151                 goto out1;
4152         }
4153 
4154         if (vp->v_type != VREG) {
4155                 resp->status = NFS3ERR_INVAL;
 
 | 
 
 
 394         struct vattr *vap;
 395         struct vattr va;
 396         struct vattr *dvap;
 397         struct vattr dva;
 398         nfs_fh3 *fhp;
 399         struct sec_ol sec = {0, 0};
 400         bool_t publicfh_flag = FALSE, auth_weak = FALSE;
 401         struct sockaddr *ca;
 402         char *name = NULL;
 403 
 404         dvap = NULL;
 405 
 406         if (exi != NULL)
 407                 exi_hold(exi);
 408 
 409         /*
 410          * Allow lookups from the root - the default
 411          * location of the public filehandle.
 412          */
 413         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 414                 ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
 415                 dvp = ZONE_ROOTVP();
 416                 VN_HOLD(dvp);
 417 
 418                 DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
 419                     cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 420                     LOOKUP3args *, args);
 421         } else {
 422                 dvp = nfs3_fhtovp(&args->what.dir, exi);
 423 
 424                 DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
 425                     cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 426                     LOOKUP3args *, args);
 427 
 428                 if (dvp == NULL) {
 429                         error = ESTALE;
 430                         goto out;
 431                 }
 432         }
 433 
 434         dva.va_mask = AT_ALL;
 435         dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;
 436 
 437         if (args->what.name == nfs3nametoolong) {
 438                 resp->status = NFS3ERR_NAMETOOLONG;
 439                 goto out1;
 440         }
 441 
 442         if (args->what.name == NULL || *(args->what.name) == '\0') {
 443                 resp->status = NFS3ERR_ACCES;
 444                 goto out1;
 445         }
 446 
 447         fhp = &args->what.dir;
 448         ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL */
 449         if (strcmp(args->what.name, "..") == 0 &&
 450             EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 451                 if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
 452                     ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
 453                         /*
 454                          * special case for ".." and 'nohide'exported root
 455                          */
 456                         if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
 457                                 resp->status = NFS3ERR_ACCES;
 458                                 goto out1;
 459                         }
 460                 } else {
 461                         resp->status = NFS3ERR_NOENT;
 462                         goto out1;
 463                 }
 464         }
 465 
 466         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 467         name = nfscmd_convname(ca, exi, args->what.name,
 468             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
 469 
 470         if (name == NULL) {
 471                 resp->status = NFS3ERR_ACCES;
 472                 goto out1;
 473         }
 474 
 475         /*
 476          * If the public filehandle is used then allow
 477          * a multi-component lookup
 478          */
 479         if (PUBLIC_FH3(&args->what.dir)) {
 480                 publicfh_flag = TRUE;
 481 
 482                 exi_rele(exi);
 483                 exi = NULL;
 484 
 485                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 486                     &exi, &sec);
 487 
 488                 /*
 489                  * Since WebNFS may bypass MOUNT, we need to ensure this
 490                  * request didn't come from an unlabeled admin_low client.
 491                  */
 492                 if (is_system_labeled() && error == 0) {
 493                         int             addr_type;
 494                         void            *ipaddr;
 495                         tsol_tpc_t      *tp;
 496 
 497                         if (ca->sa_family == AF_INET) {
 498                                 addr_type = IPV4_VERSION;
 499                                 ipaddr = &((struct sockaddr_in *)ca)->sin_addr;
 500                         } else if (ca->sa_family == AF_INET6) {
 501                                 addr_type = IPV6_VERSION;
 502                                 ipaddr = &((struct sockaddr_in6 *)
 503                                     ca)->sin6_addr;
 
 547 
 548         if (error)
 549                 goto out;
 550 
 551         if (sec.sec_flags & SEC_QUERY) {
 552                 error = makefh3_ol(&resp->resok.object, exi, sec.sec_index);
 553         } else {
 554                 error = makefh3(&resp->resok.object, vp, exi);
 555                 if (!error && publicfh_flag && !chk_clnt_sec(exi, req))
 556                         auth_weak = TRUE;
 557         }
 558 
 559         if (error) {
 560                 VN_RELE(vp);
 561                 goto out;
 562         }
 563 
 564         va.va_mask = AT_ALL;
 565         vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 566 
 567         VN_RELE(vp);
 568 
 569         resp->status = NFS3_OK;
 570         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 571         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 572 
 573         /*
 574          * If it's public fh, no 0x81, and client's flavor is
 575          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 576          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 577          */
 578         if (auth_weak)
 579                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 580 
 581         DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
 582             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 583             LOOKUP3res *, resp);
 584         VN_RELE(dvp);
 585         exi_rele(exi);
 586 
 587         return;
 588 
 589 out:
 590         if (curthread->t_flag & T_WOULDBLOCK) {
 591                 curthread->t_flag &= ~T_WOULDBLOCK;
 592                 resp->status = NFS3ERR_JUKEBOX;
 593         } else
 594                 resp->status = puterrno3(error);
 595 out1:
 596         DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
 597             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
 598             LOOKUP3res *, resp);
 599 
 600         if (exi != NULL)
 601                 exi_rele(exi);
 602 
 603         if (dvp != NULL)
 604                 VN_RELE(dvp);
 605         vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
 
1319         mblk_t *m;
1320         struct iovec *iovp;
1321         int iovcnt;
1322         int ioflag;
1323         cred_t *savecred;
1324         int in_crit = 0;
1325         int rwlock_ret = -1;
1326         caller_context_t ct;
1327 
1328         vp = nfs3_fhtovp(&args->file, exi);
1329 
1330         DTRACE_NFSV3_5(op__write__start, struct svc_req *, req,
1331             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
1332             WRITE3args *, args);
1333 
1334         if (vp == NULL) {
1335                 error = ESTALE;
1336                 goto err;
1337         }
1338 
1339         ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL. */
1340         ns = nfs3_get_srv();
1341 
1342         if (is_system_labeled()) {
1343                 bslabel_t *clabel = req->rq_label;
1344 
1345                 ASSERT(clabel != NULL);
1346                 DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
1347                     "got client label from request(1)", struct svc_req *, req);
1348 
1349                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
1350                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
1351                             exi)) {
1352                                 resp->status = NFS3ERR_ACCES;
1353                                 goto err1;
1354                         }
1355                 }
1356         }
1357 
1358         ct.cc_sysid = 0;
1359         ct.cc_pid = 0;
1360         ct.cc_caller_id = nfs3_srv_caller_id;
1361         ct.cc_flags = CC_DONTBLOCK;
 
2659                     "got client label from request(1)", struct svc_req *, req);
2660 
2661                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2662                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
2663                             exi)) {
2664                                 resp->status = NFS3ERR_ACCES;
2665                                 goto err1;
2666                         }
2667                 }
2668         }
2669 
2670         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2671         name = nfscmd_convname(ca, exi, args->object.name,
2672             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2673 
2674         if (name == NULL) {
2675                 resp->status = NFS3ERR_INVAL;
2676                 goto err1;
2677         }
2678 
2679         ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
2680         error = VOP_RMDIR(vp, name, ZONE_ROOTVP(), cr, NULL, 0);
2681 
2682         if (name != args->object.name)
2683                 kmem_free(name, MAXPATHLEN + 1);
2684 
2685         ava.va_mask = AT_ALL;
2686         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2687 
2688         /*
2689          * Force modified data and metadata out to stable storage.
2690          */
2691         (void) VOP_FSYNC(vp, 0, cr, NULL);
2692 
2693         if (error) {
2694                 /*
2695                  * System V defines rmdir to return EEXIST, not ENOTEMPTY,
2696                  * if the directory is not empty.  A System V NFS server
2697                  * needs to map NFS3ERR_EXIST to NFS3ERR_NOTEMPTY to transmit
2698                  * over the wire.
2699                  */
 
4122         vnode_t *vp;
4123         struct vattr *bvap;
4124         struct vattr bva;
4125         struct vattr *avap;
4126         struct vattr ava;
4127 
4128         bvap = NULL;
4129         avap = NULL;
4130 
4131         vp = nfs3_fhtovp(&args->file, exi);
4132 
4133         DTRACE_NFSV3_5(op__commit__start, struct svc_req *, req,
4134             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
4135             COMMIT3args *, args);
4136 
4137         if (vp == NULL) {
4138                 error = ESTALE;
4139                 goto out;
4140         }
4141 
4142         ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL. */
4143         ns = nfs3_get_srv();
4144         bva.va_mask = AT_ALL;
4145         error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4146 
4147         /*
4148          * If we can't get the attributes, then we can't do the
4149          * right access checking.  So, we'll fail the request.
4150          */
4151         if (error)
4152                 goto out;
4153 
4154         bvap = &bva;
4155 
4156         if (rdonly(ro, vp)) {
4157                 resp->status = NFS3ERR_ROFS;
4158                 goto out1;
4159         }
4160 
4161         if (vp->v_type != VREG) {
4162                 resp->status = NFS3ERR_INVAL;
 
 |