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)
|