Print this page
*** NO COMMENTS ***


   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 (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  28 /* All Rights Reserved */
  29 
  30 #include <sys/param.h>
  31 #include <sys/types.h>
  32 #include <sys/systm.h>
  33 #include <sys/cred.h>
  34 #include <sys/buf.h>
  35 #include <sys/vfs.h>
  36 #include <sys/vnode.h>
  37 #include <sys/uio.h>
  38 #include <sys/errno.h>
  39 #include <sys/sysmacros.h>
  40 #include <sys/statvfs.h>
  41 #include <sys/kmem.h>
  42 #include <sys/dirent.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/debug.h>


 365 /* ARGSUSED */
 366 void
 367 rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
 368         struct svc_req *req, cred_t *cr)
 369 {
 370         int error;
 371         vnode_t *vp;
 372         vnode_t *dvp;
 373         struct vattr *vap;
 374         struct vattr va;
 375         struct vattr *dvap;
 376         struct vattr dva;
 377         nfs_fh3 *fhp;
 378         struct sec_ol sec = {0, 0};
 379         bool_t publicfh_flag = FALSE, auth_weak = FALSE;
 380         struct sockaddr *ca;
 381         char *name = NULL;
 382 
 383         dvap = NULL;
 384 




 385         /*
 386          * Allow lookups from the root - the default
 387          * location of the public filehandle.
 388          */
 389         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 390                 dvp = rootdir;
 391                 VN_HOLD(dvp);
 392 
 393                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 394                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 395         } else {
 396                 dvp = nfs3_fhtovp(&args->what.dir, exi);
 397 
 398                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 399                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 400 
 401                 if (dvp == NULL) {
 402                         error = ESTALE;
 403                         goto out;
 404                 }


 416                 resp->status = NFS3ERR_ACCES;
 417                 goto out1;
 418         }
 419 
 420         fhp = &args->what.dir;
 421         if (strcmp(args->what.name, "..") == 0 &&
 422             EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 423                 resp->status = NFS3ERR_NOENT;
 424                 goto out1;
 425         }
 426 
 427         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 428         name = nfscmd_convname(ca, exi, args->what.name,
 429             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
 430 
 431         if (name == NULL) {
 432                 resp->status = NFS3ERR_ACCES;
 433                 goto out1;
 434         }
 435 
 436         exi_hold(exi);
 437 
 438         /*
 439          * If the public filehandle is used then allow
 440          * a multi-component lookup
 441          */
 442         if (PUBLIC_FH3(&args->what.dir)) {
 443                 struct exportinfo *new;
 444 
 445                 publicfh_flag = TRUE;
 446 
 447                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 448                     &new, &sec);
 449 
 450                 if (error == 0) {
 451                         exi_rele(exi);
 452                         exi = new;
 453                 }
 454 
 455                 /*
 456                  * Since WebNFS may bypass MOUNT, we need to ensure this
 457                  * request didn't come from an unlabeled admin_low client.


 532 
 533         resp->status = NFS3_OK;
 534         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 535         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 536 
 537         /*
 538          * If it's public fh, no 0x81, and client's flavor is
 539          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 540          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 541          */
 542         if (auth_weak)
 543                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 544 
 545         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 546             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 547         VN_RELE(dvp);
 548 
 549         return;
 550 
 551 out:
 552         /*
 553          * The passed argument exportinfo is released by the
 554          * caller, common_dispatch
 555          */
 556         exi_rele(exi);
 557 
 558         if (curthread->t_flag & T_WOULDBLOCK) {
 559                 curthread->t_flag &= ~T_WOULDBLOCK;
 560                 resp->status = NFS3ERR_JUKEBOX;
 561         } else
 562                 resp->status = puterrno3(error);
 563 out1:



 564         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 565             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 566 
 567         if (dvp != NULL)
 568                 VN_RELE(dvp);
 569         vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
 570 
 571 }
 572 
 573 void *
 574 rfs3_lookup_getfh(LOOKUP3args *args)
 575 {
 576 
 577         return (&args->what.dir);
 578 }
 579 
 580 /* ARGSUSED */
 581 void
 582 rfs3_access(ACCESS3args *args, ACCESS3res *resp, struct exportinfo *exi,
 583         struct svc_req *req, cred_t *cr)




   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 (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  28 /* All Rights Reserved */
  29 
  30 #include <sys/param.h>
  31 #include <sys/types.h>
  32 #include <sys/systm.h>
  33 #include <sys/cred.h>
  34 #include <sys/buf.h>
  35 #include <sys/vfs.h>
  36 #include <sys/vnode.h>
  37 #include <sys/uio.h>
  38 #include <sys/errno.h>
  39 #include <sys/sysmacros.h>
  40 #include <sys/statvfs.h>
  41 #include <sys/kmem.h>
  42 #include <sys/dirent.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/debug.h>


 365 /* ARGSUSED */
 366 void
 367 rfs3_lookup(LOOKUP3args *args, LOOKUP3res *resp, struct exportinfo *exi,
 368         struct svc_req *req, cred_t *cr)
 369 {
 370         int error;
 371         vnode_t *vp;
 372         vnode_t *dvp;
 373         struct vattr *vap;
 374         struct vattr va;
 375         struct vattr *dvap;
 376         struct vattr dva;
 377         nfs_fh3 *fhp;
 378         struct sec_ol sec = {0, 0};
 379         bool_t publicfh_flag = FALSE, auth_weak = FALSE;
 380         struct sockaddr *ca;
 381         char *name = NULL;
 382 
 383         dvap = NULL;
 384 
 385         /* Take an extra hold here in case of 'exi' switching */
 386         if (exi != NULL)
 387                 exi_hold(exi);
 388 
 389         /*
 390          * Allow lookups from the root - the default
 391          * location of the public filehandle.
 392          */
 393         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 394                 dvp = rootdir;
 395                 VN_HOLD(dvp);
 396 
 397                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 398                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 399         } else {
 400                 dvp = nfs3_fhtovp(&args->what.dir, exi);
 401 
 402                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 403                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 404 
 405                 if (dvp == NULL) {
 406                         error = ESTALE;
 407                         goto out;
 408                 }


 420                 resp->status = NFS3ERR_ACCES;
 421                 goto out1;
 422         }
 423 
 424         fhp = &args->what.dir;
 425         if (strcmp(args->what.name, "..") == 0 &&
 426             EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 427                 resp->status = NFS3ERR_NOENT;
 428                 goto out1;
 429         }
 430 
 431         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 432         name = nfscmd_convname(ca, exi, args->what.name,
 433             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
 434 
 435         if (name == NULL) {
 436                 resp->status = NFS3ERR_ACCES;
 437                 goto out1;
 438         }
 439 


 440         /*
 441          * If the public filehandle is used then allow
 442          * a multi-component lookup
 443          */
 444         if (PUBLIC_FH3(&args->what.dir)) {
 445                 struct exportinfo *new;
 446 
 447                 publicfh_flag = TRUE;
 448 
 449                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 450                     &new, &sec);
 451 
 452                 if (error == 0) {
 453                         exi_rele(exi);
 454                         exi = new;
 455                 }
 456 
 457                 /*
 458                  * Since WebNFS may bypass MOUNT, we need to ensure this
 459                  * request didn't come from an unlabeled admin_low client.


 534 
 535         resp->status = NFS3_OK;
 536         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 537         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 538 
 539         /*
 540          * If it's public fh, no 0x81, and client's flavor is
 541          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 542          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 543          */
 544         if (auth_weak)
 545                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 546 
 547         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 548             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 549         VN_RELE(dvp);
 550 
 551         return;
 552 
 553 out:






 554         if (curthread->t_flag & T_WOULDBLOCK) {
 555                 curthread->t_flag &= ~T_WOULDBLOCK;
 556                 resp->status = NFS3ERR_JUKEBOX;
 557         } else
 558                 resp->status = puterrno3(error);
 559 out1:
 560         if (exi != NULL)
 561                 exi_rele(exi);
 562 
 563         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 564             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 565 
 566         if (dvp != NULL)
 567                 VN_RELE(dvp);
 568         vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
 569 
 570 }
 571 
 572 void *
 573 rfs3_lookup_getfh(LOOKUP3args *args)
 574 {
 575 
 576         return (&args->what.dir);
 577 }
 578 
 579 /* ARGSUSED */
 580 void
 581 rfs3_access(ACCESS3args *args, ACCESS3res *resp, struct exportinfo *exi,
 582         struct svc_req *req, cred_t *cr)