19ec7b004SRick Macklem /*- 251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 351369649SPedro F. Giffuni * 49ec7b004SRick Macklem * Copyright (c) 1989, 1993 59ec7b004SRick Macklem * The Regents of the University of California. All rights reserved. 69ec7b004SRick Macklem * 79ec7b004SRick Macklem * This code is derived from software contributed to Berkeley by 89ec7b004SRick Macklem * Rick Macklem at The University of Guelph. 99ec7b004SRick Macklem * 109ec7b004SRick Macklem * Redistribution and use in source and binary forms, with or without 119ec7b004SRick Macklem * modification, are permitted provided that the following conditions 129ec7b004SRick Macklem * are met: 139ec7b004SRick Macklem * 1. Redistributions of source code must retain the above copyright 149ec7b004SRick Macklem * notice, this list of conditions and the following disclaimer. 159ec7b004SRick Macklem * 2. Redistributions in binary form must reproduce the above copyright 169ec7b004SRick Macklem * notice, this list of conditions and the following disclaimer in the 179ec7b004SRick Macklem * documentation and/or other materials provided with the distribution. 18fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 199ec7b004SRick Macklem * may be used to endorse or promote products derived from this software 209ec7b004SRick Macklem * without specific prior written permission. 219ec7b004SRick Macklem * 229ec7b004SRick Macklem * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 239ec7b004SRick Macklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 249ec7b004SRick Macklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 259ec7b004SRick Macklem * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 269ec7b004SRick Macklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 279ec7b004SRick Macklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 289ec7b004SRick Macklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 299ec7b004SRick Macklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 309ec7b004SRick Macklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 319ec7b004SRick Macklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 329ec7b004SRick Macklem * SUCH DAMAGE. 339ec7b004SRick Macklem * 349ec7b004SRick Macklem */ 359ec7b004SRick Macklem 369ec7b004SRick Macklem #include <sys/cdefs.h> 379ec7b004SRick Macklem /* 389ec7b004SRick Macklem * These functions support the macros and help fiddle mbuf chains for 399ec7b004SRick Macklem * the nfs op functions. They do things like create the rpc header and 409ec7b004SRick Macklem * copy data between mbuf chains and uio lists. 419ec7b004SRick Macklem */ 429ec7b004SRick Macklem #include <fs/nfs/nfsport.h> 439ec7b004SRick Macklem 449ec7b004SRick Macklem extern u_int32_t newnfs_true, newnfs_false; 459ec7b004SRick Macklem extern int nfs_pubfhset; 461f54e596SRick Macklem extern int nfsrv_clienthashsize; 471f54e596SRick Macklem extern int nfsrv_lockhashsize; 481f54e596SRick Macklem extern int nfsrv_sessionhashsize; 499ec7b004SRick Macklem extern int nfsrv_useacl; 509ec7b004SRick Macklem extern uid_t nfsrv_defaultuid; 519ec7b004SRick Macklem extern gid_t nfsrv_defaultgid; 529ec7b004SRick Macklem 537e44856eSRick Macklem NFSD_VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash); 547e44856eSRick Macklem NFSD_VNET_DECLARE(struct nfslockhashhead *, nfslockhash); 557e44856eSRick Macklem NFSD_VNET_DECLARE(struct nfssessionhash *, nfssessionhash); 567e44856eSRick Macklem NFSD_VNET_DECLARE(int, nfs_rootfhset); 577e44856eSRick Macklem NFSD_VNET_DECLARE(uid_t, nfsrv_defaultuid); 587e44856eSRick Macklem NFSD_VNET_DECLARE(gid_t, nfsrv_defaultgid); 597e44856eSRick Macklem 609ec7b004SRick Macklem char nfs_v2pubfh[NFSX_V2FH]; 6190d2dfabSRick Macklem struct nfsdontlisthead nfsrv_dontlisthead; 6290d2dfabSRick Macklem struct nfslayouthead nfsrv_recalllisthead; 639ec7b004SRick Macklem static nfstype newnfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, 649ec7b004SRick Macklem NFNON, NFCHR, NFNON }; 659ec7b004SRick Macklem extern nfstype nfsv34_type[9]; 669ec7b004SRick Macklem 67c59e4cc3SRick Macklem static u_int32_t nfsrv_isannfserr(u_int32_t); 68c59e4cc3SRick Macklem 6934f2e649SRick Macklem SYSCTL_DECL(_vfs_nfsd); 7034f2e649SRick Macklem 71f9246664SMarcelo Araujo static int enable_checkutf8 = 1; 72f9246664SMarcelo Araujo SYSCTL_INT(_vfs_nfsd, OID_AUTO, enable_checkutf8, CTLFLAG_RW, 73f9246664SMarcelo Araujo &enable_checkutf8, 0, 74f9246664SMarcelo Araujo "Enable the NFSv4 check for the UTF8 compliant name required by rfc3530"); 7534f2e649SRick Macklem 763dd6b7ffSMarcelo Araujo static int enable_nobodycheck = 1; 773dd6b7ffSMarcelo Araujo SYSCTL_INT(_vfs_nfsd, OID_AUTO, enable_nobodycheck, CTLFLAG_RW, 783dd6b7ffSMarcelo Araujo &enable_nobodycheck, 0, 793dd6b7ffSMarcelo Araujo "Enable the NFSv4 check when setting user nobody as owner"); 803dd6b7ffSMarcelo Araujo 813dd6b7ffSMarcelo Araujo static int enable_nogroupcheck = 1; 823dd6b7ffSMarcelo Araujo SYSCTL_INT(_vfs_nfsd, OID_AUTO, enable_nogroupcheck, CTLFLAG_RW, 833dd6b7ffSMarcelo Araujo &enable_nogroupcheck, 0, 843dd6b7ffSMarcelo Araujo "Enable the NFSv4 check when setting group nogroup as owner"); 853dd6b7ffSMarcelo Araujo 869ec7b004SRick Macklem static char nfsrv_hexdigit(char, int *); 879ec7b004SRick Macklem 889ec7b004SRick Macklem /* 899ec7b004SRick Macklem * Maps errno values to nfs error numbers. 909ec7b004SRick Macklem * Use NFSERR_IO as the catch all for ones not specifically defined in 91c59e4cc3SRick Macklem * RFC 1094. (It now includes the errors added for NFSv3.) 929ec7b004SRick Macklem */ 93c59e4cc3SRick Macklem static u_char nfsrv_v2errmap[NFSERR_REMOTE] = { 949ec7b004SRick Macklem NFSERR_PERM, NFSERR_NOENT, NFSERR_IO, NFSERR_IO, NFSERR_IO, 959ec7b004SRick Macklem NFSERR_NXIO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 969ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_ACCES, NFSERR_IO, NFSERR_IO, 97c59e4cc3SRick Macklem NFSERR_IO, NFSERR_EXIST, NFSERR_XDEV, NFSERR_NODEV, NFSERR_NOTDIR, 98c59e4cc3SRick Macklem NFSERR_ISDIR, NFSERR_INVAL, NFSERR_IO, NFSERR_IO, NFSERR_IO, 999ec7b004SRick Macklem NFSERR_IO, NFSERR_FBIG, NFSERR_NOSPC, NFSERR_IO, NFSERR_ROFS, 100c59e4cc3SRick Macklem NFSERR_MLINK, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 1019ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 1029ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 1039ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 1049ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 1059ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, 1069ec7b004SRick Macklem NFSERR_IO, NFSERR_IO, NFSERR_NAMETOL, NFSERR_IO, NFSERR_IO, 1079ec7b004SRick Macklem NFSERR_NOTEMPTY, NFSERR_IO, NFSERR_IO, NFSERR_DQUOT, NFSERR_STALE, 108c59e4cc3SRick Macklem NFSERR_REMOTE, 1099ec7b004SRick Macklem }; 1109ec7b004SRick Macklem 1119ec7b004SRick Macklem /* 1129ec7b004SRick Macklem * Maps errno values to nfs error numbers. 1139ec7b004SRick Macklem * Although it is not obvious whether or not NFS clients really care if 1149ec7b004SRick Macklem * a returned error value is in the specified list for the procedure, the 1159ec7b004SRick Macklem * safest thing to do is filter them appropriately. For Version 2, the 1169ec7b004SRick Macklem * X/Open XNFS document is the only specification that defines error values 1179ec7b004SRick Macklem * for each RPC (The RFC simply lists all possible error values for all RPCs), 1189ec7b004SRick Macklem * so I have decided to not do this for Version 2. 1199ec7b004SRick Macklem * The first entry is the default error return and the rest are the valid 1209ec7b004SRick Macklem * errors for that RPC in increasing numeric order. 1219ec7b004SRick Macklem */ 1229ec7b004SRick Macklem static short nfsv3err_null[] = { 1239ec7b004SRick Macklem 0, 1249ec7b004SRick Macklem 0, 1259ec7b004SRick Macklem }; 1269ec7b004SRick Macklem 1279ec7b004SRick Macklem static short nfsv3err_getattr[] = { 1289ec7b004SRick Macklem NFSERR_IO, 1299ec7b004SRick Macklem NFSERR_IO, 1309ec7b004SRick Macklem NFSERR_STALE, 1319ec7b004SRick Macklem NFSERR_BADHANDLE, 1329ec7b004SRick Macklem NFSERR_SERVERFAULT, 1339ec7b004SRick Macklem NFSERR_DELAY, 1349ec7b004SRick Macklem 0, 1359ec7b004SRick Macklem }; 1369ec7b004SRick Macklem 1379ec7b004SRick Macklem static short nfsv3err_setattr[] = { 1389ec7b004SRick Macklem NFSERR_IO, 1399ec7b004SRick Macklem NFSERR_ACCES, 1409ec7b004SRick Macklem NFSERR_PERM, 1419ec7b004SRick Macklem NFSERR_IO, 1429ec7b004SRick Macklem NFSERR_INVAL, 1439ec7b004SRick Macklem NFSERR_NOSPC, 1449ec7b004SRick Macklem NFSERR_ROFS, 1459ec7b004SRick Macklem NFSERR_DQUOT, 1469ec7b004SRick Macklem NFSERR_STALE, 1479ec7b004SRick Macklem NFSERR_BADHANDLE, 1489ec7b004SRick Macklem NFSERR_NOT_SYNC, 1499ec7b004SRick Macklem NFSERR_SERVERFAULT, 1509ec7b004SRick Macklem NFSERR_DELAY, 1519ec7b004SRick Macklem 0, 1529ec7b004SRick Macklem }; 1539ec7b004SRick Macklem 1549ec7b004SRick Macklem static short nfsv3err_lookup[] = { 1559ec7b004SRick Macklem NFSERR_IO, 1569ec7b004SRick Macklem NFSERR_NOENT, 1579ec7b004SRick Macklem NFSERR_ACCES, 1589ec7b004SRick Macklem NFSERR_NAMETOL, 1599ec7b004SRick Macklem NFSERR_IO, 1609ec7b004SRick Macklem NFSERR_NOTDIR, 1619ec7b004SRick Macklem NFSERR_STALE, 1629ec7b004SRick Macklem NFSERR_BADHANDLE, 1639ec7b004SRick Macklem NFSERR_SERVERFAULT, 1649ec7b004SRick Macklem NFSERR_DELAY, 1659ec7b004SRick Macklem 0, 1669ec7b004SRick Macklem }; 1679ec7b004SRick Macklem 1689ec7b004SRick Macklem static short nfsv3err_access[] = { 1699ec7b004SRick Macklem NFSERR_IO, 1709ec7b004SRick Macklem NFSERR_IO, 1719ec7b004SRick Macklem NFSERR_STALE, 1729ec7b004SRick Macklem NFSERR_BADHANDLE, 1739ec7b004SRick Macklem NFSERR_SERVERFAULT, 1749ec7b004SRick Macklem NFSERR_DELAY, 1759ec7b004SRick Macklem 0, 1769ec7b004SRick Macklem }; 1779ec7b004SRick Macklem 1789ec7b004SRick Macklem static short nfsv3err_readlink[] = { 1799ec7b004SRick Macklem NFSERR_IO, 1809ec7b004SRick Macklem NFSERR_IO, 1819ec7b004SRick Macklem NFSERR_ACCES, 1829ec7b004SRick Macklem NFSERR_INVAL, 1839ec7b004SRick Macklem NFSERR_STALE, 1849ec7b004SRick Macklem NFSERR_BADHANDLE, 1859ec7b004SRick Macklem NFSERR_NOTSUPP, 1869ec7b004SRick Macklem NFSERR_SERVERFAULT, 1879ec7b004SRick Macklem NFSERR_DELAY, 1889ec7b004SRick Macklem 0, 1899ec7b004SRick Macklem }; 1909ec7b004SRick Macklem 1919ec7b004SRick Macklem static short nfsv3err_read[] = { 1929ec7b004SRick Macklem NFSERR_IO, 1939ec7b004SRick Macklem NFSERR_IO, 1949ec7b004SRick Macklem NFSERR_NXIO, 1959ec7b004SRick Macklem NFSERR_ACCES, 1969ec7b004SRick Macklem NFSERR_INVAL, 1979ec7b004SRick Macklem NFSERR_STALE, 1989ec7b004SRick Macklem NFSERR_BADHANDLE, 1999ec7b004SRick Macklem NFSERR_SERVERFAULT, 2009ec7b004SRick Macklem NFSERR_DELAY, 2019ec7b004SRick Macklem 0, 2029ec7b004SRick Macklem }; 2039ec7b004SRick Macklem 2049ec7b004SRick Macklem static short nfsv3err_write[] = { 2059ec7b004SRick Macklem NFSERR_IO, 2069ec7b004SRick Macklem NFSERR_IO, 2079ec7b004SRick Macklem NFSERR_ACCES, 2089ec7b004SRick Macklem NFSERR_NOSPC, 2099ec7b004SRick Macklem NFSERR_INVAL, 2109ec7b004SRick Macklem NFSERR_FBIG, 2119ec7b004SRick Macklem NFSERR_ROFS, 2129ec7b004SRick Macklem NFSERR_DQUOT, 2139ec7b004SRick Macklem NFSERR_STALE, 2149ec7b004SRick Macklem NFSERR_BADHANDLE, 2159ec7b004SRick Macklem NFSERR_SERVERFAULT, 2169ec7b004SRick Macklem NFSERR_DELAY, 2179ec7b004SRick Macklem 0, 2189ec7b004SRick Macklem }; 2199ec7b004SRick Macklem 2209ec7b004SRick Macklem static short nfsv3err_create[] = { 2219ec7b004SRick Macklem NFSERR_IO, 2229ec7b004SRick Macklem NFSERR_EXIST, 2239ec7b004SRick Macklem NFSERR_NAMETOL, 2249ec7b004SRick Macklem NFSERR_ACCES, 2259ec7b004SRick Macklem NFSERR_IO, 2269ec7b004SRick Macklem NFSERR_NOTDIR, 2279ec7b004SRick Macklem NFSERR_NOSPC, 2289ec7b004SRick Macklem NFSERR_ROFS, 2299ec7b004SRick Macklem NFSERR_DQUOT, 2309ec7b004SRick Macklem NFSERR_STALE, 2319ec7b004SRick Macklem NFSERR_BADHANDLE, 2329ec7b004SRick Macklem NFSERR_NOTSUPP, 2339ec7b004SRick Macklem NFSERR_SERVERFAULT, 2349ec7b004SRick Macklem NFSERR_DELAY, 2359ec7b004SRick Macklem 0, 2369ec7b004SRick Macklem }; 2379ec7b004SRick Macklem 2389ec7b004SRick Macklem static short nfsv3err_mkdir[] = { 2399ec7b004SRick Macklem NFSERR_IO, 2409ec7b004SRick Macklem NFSERR_EXIST, 2419ec7b004SRick Macklem NFSERR_ACCES, 2429ec7b004SRick Macklem NFSERR_NAMETOL, 2439ec7b004SRick Macklem NFSERR_IO, 2449ec7b004SRick Macklem NFSERR_NOTDIR, 2459ec7b004SRick Macklem NFSERR_NOSPC, 2469ec7b004SRick Macklem NFSERR_ROFS, 2479ec7b004SRick Macklem NFSERR_DQUOT, 2489ec7b004SRick Macklem NFSERR_STALE, 2499ec7b004SRick Macklem NFSERR_BADHANDLE, 2509ec7b004SRick Macklem NFSERR_NOTSUPP, 2519ec7b004SRick Macklem NFSERR_SERVERFAULT, 2529ec7b004SRick Macklem NFSERR_DELAY, 2539ec7b004SRick Macklem 0, 2549ec7b004SRick Macklem }; 2559ec7b004SRick Macklem 2569ec7b004SRick Macklem static short nfsv3err_symlink[] = { 2579ec7b004SRick Macklem NFSERR_IO, 2589ec7b004SRick Macklem NFSERR_ACCES, 2599ec7b004SRick Macklem NFSERR_EXIST, 2609ec7b004SRick Macklem NFSERR_NAMETOL, 2619ec7b004SRick Macklem NFSERR_NOSPC, 2629ec7b004SRick Macklem NFSERR_IO, 2639ec7b004SRick Macklem NFSERR_NOTDIR, 2649ec7b004SRick Macklem NFSERR_ROFS, 2659ec7b004SRick Macklem NFSERR_DQUOT, 2669ec7b004SRick Macklem NFSERR_STALE, 2679ec7b004SRick Macklem NFSERR_BADHANDLE, 2689ec7b004SRick Macklem NFSERR_NOTSUPP, 2699ec7b004SRick Macklem NFSERR_SERVERFAULT, 2709ec7b004SRick Macklem NFSERR_DELAY, 2719ec7b004SRick Macklem 0, 2729ec7b004SRick Macklem }; 2739ec7b004SRick Macklem 2749ec7b004SRick Macklem static short nfsv3err_mknod[] = { 2759ec7b004SRick Macklem NFSERR_IO, 2769ec7b004SRick Macklem NFSERR_ACCES, 2779ec7b004SRick Macklem NFSERR_EXIST, 2789ec7b004SRick Macklem NFSERR_NAMETOL, 2799ec7b004SRick Macklem NFSERR_NOSPC, 2809ec7b004SRick Macklem NFSERR_IO, 2819ec7b004SRick Macklem NFSERR_NOTDIR, 2829ec7b004SRick Macklem NFSERR_ROFS, 2839ec7b004SRick Macklem NFSERR_DQUOT, 2849ec7b004SRick Macklem NFSERR_STALE, 2859ec7b004SRick Macklem NFSERR_BADHANDLE, 2869ec7b004SRick Macklem NFSERR_NOTSUPP, 2879ec7b004SRick Macklem NFSERR_SERVERFAULT, 2889ec7b004SRick Macklem NFSERR_DELAY, 2899ec7b004SRick Macklem NFSERR_BADTYPE, 2909ec7b004SRick Macklem 0, 2919ec7b004SRick Macklem }; 2929ec7b004SRick Macklem 2939ec7b004SRick Macklem static short nfsv3err_remove[] = { 2949ec7b004SRick Macklem NFSERR_IO, 2959ec7b004SRick Macklem NFSERR_NOENT, 2969ec7b004SRick Macklem NFSERR_ACCES, 2979ec7b004SRick Macklem NFSERR_NAMETOL, 2989ec7b004SRick Macklem NFSERR_IO, 2999ec7b004SRick Macklem NFSERR_NOTDIR, 3009ec7b004SRick Macklem NFSERR_ROFS, 3019ec7b004SRick Macklem NFSERR_STALE, 3029ec7b004SRick Macklem NFSERR_BADHANDLE, 3039ec7b004SRick Macklem NFSERR_SERVERFAULT, 3049ec7b004SRick Macklem NFSERR_DELAY, 3059ec7b004SRick Macklem 0, 3069ec7b004SRick Macklem }; 3079ec7b004SRick Macklem 3089ec7b004SRick Macklem static short nfsv3err_rmdir[] = { 3099ec7b004SRick Macklem NFSERR_IO, 3109ec7b004SRick Macklem NFSERR_NOENT, 3119ec7b004SRick Macklem NFSERR_ACCES, 3129ec7b004SRick Macklem NFSERR_NOTDIR, 3139ec7b004SRick Macklem NFSERR_NAMETOL, 3149ec7b004SRick Macklem NFSERR_IO, 3159ec7b004SRick Macklem NFSERR_EXIST, 3169ec7b004SRick Macklem NFSERR_INVAL, 3179ec7b004SRick Macklem NFSERR_ROFS, 3189ec7b004SRick Macklem NFSERR_NOTEMPTY, 3199ec7b004SRick Macklem NFSERR_STALE, 3209ec7b004SRick Macklem NFSERR_BADHANDLE, 3219ec7b004SRick Macklem NFSERR_NOTSUPP, 3229ec7b004SRick Macklem NFSERR_SERVERFAULT, 3239ec7b004SRick Macklem NFSERR_DELAY, 3249ec7b004SRick Macklem 0, 3259ec7b004SRick Macklem }; 3269ec7b004SRick Macklem 3279ec7b004SRick Macklem static short nfsv3err_rename[] = { 3289ec7b004SRick Macklem NFSERR_IO, 3299ec7b004SRick Macklem NFSERR_NOENT, 3309ec7b004SRick Macklem NFSERR_ACCES, 3319ec7b004SRick Macklem NFSERR_EXIST, 3329ec7b004SRick Macklem NFSERR_NAMETOL, 3339ec7b004SRick Macklem NFSERR_XDEV, 3349ec7b004SRick Macklem NFSERR_IO, 3359ec7b004SRick Macklem NFSERR_NOTDIR, 3369ec7b004SRick Macklem NFSERR_ISDIR, 3379ec7b004SRick Macklem NFSERR_INVAL, 3389ec7b004SRick Macklem NFSERR_NOSPC, 3399ec7b004SRick Macklem NFSERR_ROFS, 3409ec7b004SRick Macklem NFSERR_MLINK, 3419ec7b004SRick Macklem NFSERR_NOTEMPTY, 3429ec7b004SRick Macklem NFSERR_DQUOT, 3439ec7b004SRick Macklem NFSERR_STALE, 3449ec7b004SRick Macklem NFSERR_BADHANDLE, 3459ec7b004SRick Macklem NFSERR_NOTSUPP, 3469ec7b004SRick Macklem NFSERR_SERVERFAULT, 3479ec7b004SRick Macklem NFSERR_DELAY, 3489ec7b004SRick Macklem 0, 3499ec7b004SRick Macklem }; 3509ec7b004SRick Macklem 3519ec7b004SRick Macklem static short nfsv3err_link[] = { 3529ec7b004SRick Macklem NFSERR_IO, 3539ec7b004SRick Macklem NFSERR_ACCES, 3549ec7b004SRick Macklem NFSERR_EXIST, 3559ec7b004SRick Macklem NFSERR_NAMETOL, 3569ec7b004SRick Macklem NFSERR_IO, 3579ec7b004SRick Macklem NFSERR_XDEV, 3589ec7b004SRick Macklem NFSERR_NOTDIR, 3599ec7b004SRick Macklem NFSERR_INVAL, 3609ec7b004SRick Macklem NFSERR_NOSPC, 3619ec7b004SRick Macklem NFSERR_ROFS, 3629ec7b004SRick Macklem NFSERR_MLINK, 3639ec7b004SRick Macklem NFSERR_DQUOT, 3649ec7b004SRick Macklem NFSERR_STALE, 3659ec7b004SRick Macklem NFSERR_BADHANDLE, 3669ec7b004SRick Macklem NFSERR_NOTSUPP, 3679ec7b004SRick Macklem NFSERR_SERVERFAULT, 3689ec7b004SRick Macklem NFSERR_DELAY, 3699ec7b004SRick Macklem 0, 3709ec7b004SRick Macklem }; 3719ec7b004SRick Macklem 3729ec7b004SRick Macklem static short nfsv3err_readdir[] = { 3739ec7b004SRick Macklem NFSERR_IO, 3749ec7b004SRick Macklem NFSERR_ACCES, 3759ec7b004SRick Macklem NFSERR_NOTDIR, 3769ec7b004SRick Macklem NFSERR_IO, 3779ec7b004SRick Macklem NFSERR_STALE, 3789ec7b004SRick Macklem NFSERR_BADHANDLE, 3799ec7b004SRick Macklem NFSERR_BAD_COOKIE, 3809ec7b004SRick Macklem NFSERR_TOOSMALL, 3819ec7b004SRick Macklem NFSERR_SERVERFAULT, 3829ec7b004SRick Macklem NFSERR_DELAY, 3839ec7b004SRick Macklem 0, 3849ec7b004SRick Macklem }; 3859ec7b004SRick Macklem 3869ec7b004SRick Macklem static short nfsv3err_readdirplus[] = { 3879ec7b004SRick Macklem NFSERR_IO, 3889ec7b004SRick Macklem NFSERR_ACCES, 3899ec7b004SRick Macklem NFSERR_NOTDIR, 3909ec7b004SRick Macklem NFSERR_IO, 3919ec7b004SRick Macklem NFSERR_STALE, 3929ec7b004SRick Macklem NFSERR_BADHANDLE, 3939ec7b004SRick Macklem NFSERR_BAD_COOKIE, 3949ec7b004SRick Macklem NFSERR_NOTSUPP, 3959ec7b004SRick Macklem NFSERR_TOOSMALL, 3969ec7b004SRick Macklem NFSERR_SERVERFAULT, 3979ec7b004SRick Macklem NFSERR_DELAY, 3989ec7b004SRick Macklem 0, 3999ec7b004SRick Macklem }; 4009ec7b004SRick Macklem 4019ec7b004SRick Macklem static short nfsv3err_fsstat[] = { 4029ec7b004SRick Macklem NFSERR_IO, 4039ec7b004SRick Macklem NFSERR_IO, 4049ec7b004SRick Macklem NFSERR_STALE, 4059ec7b004SRick Macklem NFSERR_BADHANDLE, 4069ec7b004SRick Macklem NFSERR_SERVERFAULT, 4079ec7b004SRick Macklem NFSERR_DELAY, 4089ec7b004SRick Macklem 0, 4099ec7b004SRick Macklem }; 4109ec7b004SRick Macklem 4119ec7b004SRick Macklem static short nfsv3err_fsinfo[] = { 4129ec7b004SRick Macklem NFSERR_STALE, 4139ec7b004SRick Macklem NFSERR_STALE, 4149ec7b004SRick Macklem NFSERR_BADHANDLE, 4159ec7b004SRick Macklem NFSERR_SERVERFAULT, 4169ec7b004SRick Macklem NFSERR_DELAY, 4179ec7b004SRick Macklem 0, 4189ec7b004SRick Macklem }; 4199ec7b004SRick Macklem 4209ec7b004SRick Macklem static short nfsv3err_pathconf[] = { 4219ec7b004SRick Macklem NFSERR_STALE, 4229ec7b004SRick Macklem NFSERR_STALE, 4239ec7b004SRick Macklem NFSERR_BADHANDLE, 4249ec7b004SRick Macklem NFSERR_SERVERFAULT, 4259ec7b004SRick Macklem NFSERR_DELAY, 4269ec7b004SRick Macklem 0, 4279ec7b004SRick Macklem }; 4289ec7b004SRick Macklem 4299ec7b004SRick Macklem static short nfsv3err_commit[] = { 4309ec7b004SRick Macklem NFSERR_IO, 4319ec7b004SRick Macklem NFSERR_IO, 4329ec7b004SRick Macklem NFSERR_STALE, 4339ec7b004SRick Macklem NFSERR_BADHANDLE, 4349ec7b004SRick Macklem NFSERR_SERVERFAULT, 4359ec7b004SRick Macklem NFSERR_DELAY, 4369ec7b004SRick Macklem 0, 4379ec7b004SRick Macklem }; 4389ec7b004SRick Macklem 4399ec7b004SRick Macklem static short *nfsrv_v3errmap[] = { 4409ec7b004SRick Macklem nfsv3err_null, 4419ec7b004SRick Macklem nfsv3err_getattr, 4429ec7b004SRick Macklem nfsv3err_setattr, 4439ec7b004SRick Macklem nfsv3err_lookup, 4449ec7b004SRick Macklem nfsv3err_access, 4459ec7b004SRick Macklem nfsv3err_readlink, 4469ec7b004SRick Macklem nfsv3err_read, 4479ec7b004SRick Macklem nfsv3err_write, 4489ec7b004SRick Macklem nfsv3err_create, 4499ec7b004SRick Macklem nfsv3err_mkdir, 4509ec7b004SRick Macklem nfsv3err_symlink, 4519ec7b004SRick Macklem nfsv3err_mknod, 4529ec7b004SRick Macklem nfsv3err_remove, 4539ec7b004SRick Macklem nfsv3err_rmdir, 4549ec7b004SRick Macklem nfsv3err_rename, 4559ec7b004SRick Macklem nfsv3err_link, 4569ec7b004SRick Macklem nfsv3err_readdir, 4579ec7b004SRick Macklem nfsv3err_readdirplus, 4589ec7b004SRick Macklem nfsv3err_fsstat, 4599ec7b004SRick Macklem nfsv3err_fsinfo, 4609ec7b004SRick Macklem nfsv3err_pathconf, 4619ec7b004SRick Macklem nfsv3err_commit, 4629ec7b004SRick Macklem }; 4639ec7b004SRick Macklem 4649ec7b004SRick Macklem /* 4659ec7b004SRick Macklem * And the same for V4. 4669ec7b004SRick Macklem */ 4679ec7b004SRick Macklem static short nfsv4err_null[] = { 4689ec7b004SRick Macklem 0, 4699ec7b004SRick Macklem 0, 4709ec7b004SRick Macklem }; 4719ec7b004SRick Macklem 4729ec7b004SRick Macklem static short nfsv4err_access[] = { 4739ec7b004SRick Macklem NFSERR_IO, 4749ec7b004SRick Macklem NFSERR_ACCES, 4759ec7b004SRick Macklem NFSERR_BADHANDLE, 4769ec7b004SRick Macklem NFSERR_BADXDR, 4779ec7b004SRick Macklem NFSERR_DELAY, 4789ec7b004SRick Macklem NFSERR_FHEXPIRED, 4799ec7b004SRick Macklem NFSERR_INVAL, 4809ec7b004SRick Macklem NFSERR_IO, 4819ec7b004SRick Macklem NFSERR_MOVED, 4829ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 4839ec7b004SRick Macklem NFSERR_RESOURCE, 4849ec7b004SRick Macklem NFSERR_SERVERFAULT, 4859ec7b004SRick Macklem NFSERR_STALE, 4869ec7b004SRick Macklem 0, 4879ec7b004SRick Macklem }; 4889ec7b004SRick Macklem 4899ec7b004SRick Macklem static short nfsv4err_close[] = { 4909ec7b004SRick Macklem NFSERR_EXPIRED, 4919ec7b004SRick Macklem NFSERR_ADMINREVOKED, 4929ec7b004SRick Macklem NFSERR_BADHANDLE, 4939ec7b004SRick Macklem NFSERR_BADSEQID, 4949ec7b004SRick Macklem NFSERR_BADSTATEID, 4959ec7b004SRick Macklem NFSERR_BADXDR, 4969ec7b004SRick Macklem NFSERR_DELAY, 4979ec7b004SRick Macklem NFSERR_EXPIRED, 4989ec7b004SRick Macklem NFSERR_FHEXPIRED, 4999ec7b004SRick Macklem NFSERR_INVAL, 5009ec7b004SRick Macklem NFSERR_ISDIR, 5019ec7b004SRick Macklem NFSERR_LEASEMOVED, 5029ec7b004SRick Macklem NFSERR_LOCKSHELD, 5039ec7b004SRick Macklem NFSERR_MOVED, 5049ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 5059ec7b004SRick Macklem NFSERR_OLDSTATEID, 5069ec7b004SRick Macklem NFSERR_RESOURCE, 5079ec7b004SRick Macklem NFSERR_SERVERFAULT, 5089ec7b004SRick Macklem NFSERR_STALE, 5099ec7b004SRick Macklem NFSERR_STALESTATEID, 5109ec7b004SRick Macklem 0, 5119ec7b004SRick Macklem }; 5129ec7b004SRick Macklem 5139ec7b004SRick Macklem static short nfsv4err_commit[] = { 5149ec7b004SRick Macklem NFSERR_IO, 5159ec7b004SRick Macklem NFSERR_ACCES, 5169ec7b004SRick Macklem NFSERR_BADHANDLE, 5179ec7b004SRick Macklem NFSERR_BADXDR, 5189ec7b004SRick Macklem NFSERR_FHEXPIRED, 5199ec7b004SRick Macklem NFSERR_INVAL, 5209ec7b004SRick Macklem NFSERR_IO, 5219ec7b004SRick Macklem NFSERR_ISDIR, 5229ec7b004SRick Macklem NFSERR_MOVED, 5239ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 5249ec7b004SRick Macklem NFSERR_RESOURCE, 5259ec7b004SRick Macklem NFSERR_ROFS, 5269ec7b004SRick Macklem NFSERR_SERVERFAULT, 5279ec7b004SRick Macklem NFSERR_STALE, 5289ec7b004SRick Macklem 0, 5299ec7b004SRick Macklem }; 5309ec7b004SRick Macklem 5319ec7b004SRick Macklem static short nfsv4err_create[] = { 5329ec7b004SRick Macklem NFSERR_IO, 5339ec7b004SRick Macklem NFSERR_ACCES, 5349ec7b004SRick Macklem NFSERR_ATTRNOTSUPP, 5359ec7b004SRick Macklem NFSERR_BADCHAR, 5369ec7b004SRick Macklem NFSERR_BADHANDLE, 5379ec7b004SRick Macklem NFSERR_BADNAME, 5389ec7b004SRick Macklem NFSERR_BADOWNER, 5399ec7b004SRick Macklem NFSERR_BADTYPE, 5409ec7b004SRick Macklem NFSERR_BADXDR, 5419ec7b004SRick Macklem NFSERR_DELAY, 5429ec7b004SRick Macklem NFSERR_DQUOT, 5439ec7b004SRick Macklem NFSERR_EXIST, 5449ec7b004SRick Macklem NFSERR_FHEXPIRED, 5459ec7b004SRick Macklem NFSERR_INVAL, 5469ec7b004SRick Macklem NFSERR_IO, 5479ec7b004SRick Macklem NFSERR_MOVED, 5489ec7b004SRick Macklem NFSERR_NAMETOL, 5499ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 5509ec7b004SRick Macklem NFSERR_NOSPC, 5519ec7b004SRick Macklem NFSERR_NOTDIR, 5529ec7b004SRick Macklem NFSERR_PERM, 5539ec7b004SRick Macklem NFSERR_RESOURCE, 5549ec7b004SRick Macklem NFSERR_ROFS, 5559ec7b004SRick Macklem NFSERR_SERVERFAULT, 5569ec7b004SRick Macklem NFSERR_STALE, 5579ec7b004SRick Macklem 0, 5589ec7b004SRick Macklem }; 5599ec7b004SRick Macklem 5609ec7b004SRick Macklem static short nfsv4err_delegpurge[] = { 5619ec7b004SRick Macklem NFSERR_SERVERFAULT, 5629ec7b004SRick Macklem NFSERR_BADXDR, 5639ec7b004SRick Macklem NFSERR_NOTSUPP, 5649ec7b004SRick Macklem NFSERR_LEASEMOVED, 5659ec7b004SRick Macklem NFSERR_MOVED, 5669ec7b004SRick Macklem NFSERR_RESOURCE, 5679ec7b004SRick Macklem NFSERR_SERVERFAULT, 5689ec7b004SRick Macklem NFSERR_STALECLIENTID, 5699ec7b004SRick Macklem 0, 5709ec7b004SRick Macklem }; 5719ec7b004SRick Macklem 5729ec7b004SRick Macklem static short nfsv4err_delegreturn[] = { 5739ec7b004SRick Macklem NFSERR_SERVERFAULT, 5749ec7b004SRick Macklem NFSERR_ADMINREVOKED, 5759ec7b004SRick Macklem NFSERR_BADSTATEID, 5769ec7b004SRick Macklem NFSERR_BADXDR, 5779ec7b004SRick Macklem NFSERR_EXPIRED, 5789ec7b004SRick Macklem NFSERR_INVAL, 5799ec7b004SRick Macklem NFSERR_LEASEMOVED, 5809ec7b004SRick Macklem NFSERR_MOVED, 5819ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 5829ec7b004SRick Macklem NFSERR_NOTSUPP, 5839ec7b004SRick Macklem NFSERR_OLDSTATEID, 5849ec7b004SRick Macklem NFSERR_RESOURCE, 5859ec7b004SRick Macklem NFSERR_SERVERFAULT, 5869ec7b004SRick Macklem NFSERR_STALE, 5879ec7b004SRick Macklem NFSERR_STALESTATEID, 5889ec7b004SRick Macklem 0, 5899ec7b004SRick Macklem }; 5909ec7b004SRick Macklem 5919ec7b004SRick Macklem static short nfsv4err_getattr[] = { 5929ec7b004SRick Macklem NFSERR_IO, 5939ec7b004SRick Macklem NFSERR_ACCES, 5949ec7b004SRick Macklem NFSERR_BADHANDLE, 5959ec7b004SRick Macklem NFSERR_BADXDR, 5969ec7b004SRick Macklem NFSERR_DELAY, 5979ec7b004SRick Macklem NFSERR_FHEXPIRED, 5989ec7b004SRick Macklem NFSERR_INVAL, 5999ec7b004SRick Macklem NFSERR_IO, 6009ec7b004SRick Macklem NFSERR_MOVED, 6019ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 6029ec7b004SRick Macklem NFSERR_RESOURCE, 6039ec7b004SRick Macklem NFSERR_SERVERFAULT, 6049ec7b004SRick Macklem NFSERR_STALE, 6059ec7b004SRick Macklem 0, 6069ec7b004SRick Macklem }; 6079ec7b004SRick Macklem 6089ec7b004SRick Macklem static short nfsv4err_getfh[] = { 6099ec7b004SRick Macklem NFSERR_BADHANDLE, 6109ec7b004SRick Macklem NFSERR_BADHANDLE, 6119ec7b004SRick Macklem NFSERR_FHEXPIRED, 6129ec7b004SRick Macklem NFSERR_MOVED, 6139ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 6149ec7b004SRick Macklem NFSERR_RESOURCE, 6159ec7b004SRick Macklem NFSERR_SERVERFAULT, 6169ec7b004SRick Macklem NFSERR_STALE, 6179ec7b004SRick Macklem 0, 6189ec7b004SRick Macklem }; 6199ec7b004SRick Macklem 6209ec7b004SRick Macklem static short nfsv4err_link[] = { 6219ec7b004SRick Macklem NFSERR_IO, 6229ec7b004SRick Macklem NFSERR_ACCES, 6239ec7b004SRick Macklem NFSERR_BADCHAR, 6249ec7b004SRick Macklem NFSERR_BADHANDLE, 6259ec7b004SRick Macklem NFSERR_BADNAME, 6269ec7b004SRick Macklem NFSERR_BADXDR, 6279ec7b004SRick Macklem NFSERR_DELAY, 6289ec7b004SRick Macklem NFSERR_DQUOT, 6299ec7b004SRick Macklem NFSERR_EXIST, 6309ec7b004SRick Macklem NFSERR_FHEXPIRED, 6319ec7b004SRick Macklem NFSERR_FILEOPEN, 6329ec7b004SRick Macklem NFSERR_INVAL, 6339ec7b004SRick Macklem NFSERR_IO, 6349ec7b004SRick Macklem NFSERR_ISDIR, 6359ec7b004SRick Macklem NFSERR_MLINK, 6369ec7b004SRick Macklem NFSERR_MOVED, 6379ec7b004SRick Macklem NFSERR_NAMETOL, 6389ec7b004SRick Macklem NFSERR_NOENT, 6399ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 6409ec7b004SRick Macklem NFSERR_NOSPC, 6419ec7b004SRick Macklem NFSERR_NOTDIR, 6429ec7b004SRick Macklem NFSERR_NOTSUPP, 6439ec7b004SRick Macklem NFSERR_RESOURCE, 6449ec7b004SRick Macklem NFSERR_ROFS, 6459ec7b004SRick Macklem NFSERR_SERVERFAULT, 6469ec7b004SRick Macklem NFSERR_STALE, 6479ec7b004SRick Macklem NFSERR_WRONGSEC, 6489ec7b004SRick Macklem NFSERR_XDEV, 6499ec7b004SRick Macklem 0, 6509ec7b004SRick Macklem }; 6519ec7b004SRick Macklem 6529ec7b004SRick Macklem static short nfsv4err_lock[] = { 6539ec7b004SRick Macklem NFSERR_SERVERFAULT, 6549ec7b004SRick Macklem NFSERR_ACCES, 6559ec7b004SRick Macklem NFSERR_ADMINREVOKED, 6569ec7b004SRick Macklem NFSERR_BADHANDLE, 6579ec7b004SRick Macklem NFSERR_BADRANGE, 6589ec7b004SRick Macklem NFSERR_BADSEQID, 6599ec7b004SRick Macklem NFSERR_BADSTATEID, 6609ec7b004SRick Macklem NFSERR_BADXDR, 6619ec7b004SRick Macklem NFSERR_DEADLOCK, 6629ec7b004SRick Macklem NFSERR_DELAY, 6639ec7b004SRick Macklem NFSERR_DENIED, 6649ec7b004SRick Macklem NFSERR_EXPIRED, 6659ec7b004SRick Macklem NFSERR_FHEXPIRED, 6669ec7b004SRick Macklem NFSERR_GRACE, 6679ec7b004SRick Macklem NFSERR_INVAL, 6689ec7b004SRick Macklem NFSERR_ISDIR, 6699ec7b004SRick Macklem NFSERR_LEASEMOVED, 6709ec7b004SRick Macklem NFSERR_LOCKNOTSUPP, 6719ec7b004SRick Macklem NFSERR_LOCKRANGE, 6729ec7b004SRick Macklem NFSERR_MOVED, 6739ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 6749ec7b004SRick Macklem NFSERR_NOGRACE, 6759ec7b004SRick Macklem NFSERR_OLDSTATEID, 6769ec7b004SRick Macklem NFSERR_OPENMODE, 6779ec7b004SRick Macklem NFSERR_RECLAIMBAD, 6789ec7b004SRick Macklem NFSERR_RECLAIMCONFLICT, 6799ec7b004SRick Macklem NFSERR_RESOURCE, 6809ec7b004SRick Macklem NFSERR_SERVERFAULT, 6819ec7b004SRick Macklem NFSERR_STALE, 6829ec7b004SRick Macklem NFSERR_STALECLIENTID, 6839ec7b004SRick Macklem NFSERR_STALESTATEID, 6849ec7b004SRick Macklem 0, 6859ec7b004SRick Macklem }; 6869ec7b004SRick Macklem 6879ec7b004SRick Macklem static short nfsv4err_lockt[] = { 6889ec7b004SRick Macklem NFSERR_SERVERFAULT, 6899ec7b004SRick Macklem NFSERR_ACCES, 6909ec7b004SRick Macklem NFSERR_BADHANDLE, 6919ec7b004SRick Macklem NFSERR_BADRANGE, 6929ec7b004SRick Macklem NFSERR_BADXDR, 6939ec7b004SRick Macklem NFSERR_DELAY, 6949ec7b004SRick Macklem NFSERR_DENIED, 6959ec7b004SRick Macklem NFSERR_FHEXPIRED, 6969ec7b004SRick Macklem NFSERR_GRACE, 6979ec7b004SRick Macklem NFSERR_INVAL, 6989ec7b004SRick Macklem NFSERR_ISDIR, 6999ec7b004SRick Macklem NFSERR_LEASEMOVED, 7009ec7b004SRick Macklem NFSERR_LOCKRANGE, 7019ec7b004SRick Macklem NFSERR_MOVED, 7029ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 7039ec7b004SRick Macklem NFSERR_RESOURCE, 7049ec7b004SRick Macklem NFSERR_SERVERFAULT, 7059ec7b004SRick Macklem NFSERR_STALE, 7069ec7b004SRick Macklem NFSERR_STALECLIENTID, 7079ec7b004SRick Macklem 0, 7089ec7b004SRick Macklem }; 7099ec7b004SRick Macklem 7109ec7b004SRick Macklem static short nfsv4err_locku[] = { 7119ec7b004SRick Macklem NFSERR_SERVERFAULT, 7129ec7b004SRick Macklem NFSERR_ACCES, 7139ec7b004SRick Macklem NFSERR_ADMINREVOKED, 7149ec7b004SRick Macklem NFSERR_BADHANDLE, 7159ec7b004SRick Macklem NFSERR_BADRANGE, 7169ec7b004SRick Macklem NFSERR_BADSEQID, 7179ec7b004SRick Macklem NFSERR_BADSTATEID, 7189ec7b004SRick Macklem NFSERR_BADXDR, 7199ec7b004SRick Macklem NFSERR_EXPIRED, 7209ec7b004SRick Macklem NFSERR_FHEXPIRED, 7219ec7b004SRick Macklem NFSERR_GRACE, 7229ec7b004SRick Macklem NFSERR_INVAL, 7239ec7b004SRick Macklem NFSERR_ISDIR, 7249ec7b004SRick Macklem NFSERR_LEASEMOVED, 7259ec7b004SRick Macklem NFSERR_LOCKRANGE, 7269ec7b004SRick Macklem NFSERR_MOVED, 7279ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 7289ec7b004SRick Macklem NFSERR_OLDSTATEID, 7299ec7b004SRick Macklem NFSERR_RESOURCE, 7309ec7b004SRick Macklem NFSERR_SERVERFAULT, 7319ec7b004SRick Macklem NFSERR_STALE, 7329ec7b004SRick Macklem NFSERR_STALESTATEID, 7339ec7b004SRick Macklem 0, 7349ec7b004SRick Macklem }; 7359ec7b004SRick Macklem 7369ec7b004SRick Macklem static short nfsv4err_lookup[] = { 7379ec7b004SRick Macklem NFSERR_IO, 7389ec7b004SRick Macklem NFSERR_ACCES, 7399ec7b004SRick Macklem NFSERR_BADCHAR, 7409ec7b004SRick Macklem NFSERR_BADHANDLE, 7419ec7b004SRick Macklem NFSERR_BADNAME, 7429ec7b004SRick Macklem NFSERR_BADXDR, 7439ec7b004SRick Macklem NFSERR_FHEXPIRED, 7449ec7b004SRick Macklem NFSERR_INVAL, 7459ec7b004SRick Macklem NFSERR_IO, 7469ec7b004SRick Macklem NFSERR_MOVED, 7479ec7b004SRick Macklem NFSERR_NAMETOL, 7489ec7b004SRick Macklem NFSERR_NOENT, 7499ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 7509ec7b004SRick Macklem NFSERR_NOTDIR, 7519ec7b004SRick Macklem NFSERR_RESOURCE, 7529ec7b004SRick Macklem NFSERR_SERVERFAULT, 7539ec7b004SRick Macklem NFSERR_STALE, 7549ec7b004SRick Macklem NFSERR_SYMLINK, 7559ec7b004SRick Macklem NFSERR_WRONGSEC, 7569ec7b004SRick Macklem 0, 7579ec7b004SRick Macklem }; 7589ec7b004SRick Macklem 7599ec7b004SRick Macklem static short nfsv4err_lookupp[] = { 7609ec7b004SRick Macklem NFSERR_IO, 7619ec7b004SRick Macklem NFSERR_ACCES, 7629ec7b004SRick Macklem NFSERR_BADHANDLE, 7639ec7b004SRick Macklem NFSERR_FHEXPIRED, 7649ec7b004SRick Macklem NFSERR_IO, 7659ec7b004SRick Macklem NFSERR_MOVED, 7669ec7b004SRick Macklem NFSERR_NOENT, 7679ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 7689ec7b004SRick Macklem NFSERR_NOTDIR, 7699ec7b004SRick Macklem NFSERR_RESOURCE, 7709ec7b004SRick Macklem NFSERR_SERVERFAULT, 7719ec7b004SRick Macklem NFSERR_STALE, 7729ec7b004SRick Macklem 0, 7739ec7b004SRick Macklem }; 7749ec7b004SRick Macklem 7759ec7b004SRick Macklem static short nfsv4err_nverify[] = { 7769ec7b004SRick Macklem NFSERR_IO, 7779ec7b004SRick Macklem NFSERR_ACCES, 7789ec7b004SRick Macklem NFSERR_ATTRNOTSUPP, 7799ec7b004SRick Macklem NFSERR_BADCHAR, 7809ec7b004SRick Macklem NFSERR_BADHANDLE, 7819ec7b004SRick Macklem NFSERR_BADXDR, 7829ec7b004SRick Macklem NFSERR_DELAY, 7839ec7b004SRick Macklem NFSERR_FHEXPIRED, 7849ec7b004SRick Macklem NFSERR_INVAL, 7859ec7b004SRick Macklem NFSERR_IO, 7869ec7b004SRick Macklem NFSERR_MOVED, 7879ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 7889ec7b004SRick Macklem NFSERR_RESOURCE, 7899ec7b004SRick Macklem NFSERR_SAME, 7909ec7b004SRick Macklem NFSERR_SERVERFAULT, 7919ec7b004SRick Macklem NFSERR_STALE, 7929ec7b004SRick Macklem 0, 7939ec7b004SRick Macklem }; 7949ec7b004SRick Macklem 7959ec7b004SRick Macklem static short nfsv4err_open[] = { 7969ec7b004SRick Macklem NFSERR_IO, 7979ec7b004SRick Macklem NFSERR_ACCES, 7989ec7b004SRick Macklem NFSERR_ADMINREVOKED, 7999ec7b004SRick Macklem NFSERR_ATTRNOTSUPP, 8009ec7b004SRick Macklem NFSERR_BADCHAR, 8019ec7b004SRick Macklem NFSERR_BADHANDLE, 8029ec7b004SRick Macklem NFSERR_BADNAME, 8039ec7b004SRick Macklem NFSERR_BADOWNER, 8049ec7b004SRick Macklem NFSERR_BADSEQID, 8059ec7b004SRick Macklem NFSERR_BADXDR, 8069ec7b004SRick Macklem NFSERR_DELAY, 8079ec7b004SRick Macklem NFSERR_DQUOT, 8089ec7b004SRick Macklem NFSERR_EXIST, 8099ec7b004SRick Macklem NFSERR_EXPIRED, 8109ec7b004SRick Macklem NFSERR_FHEXPIRED, 8119ec7b004SRick Macklem NFSERR_GRACE, 8129ec7b004SRick Macklem NFSERR_IO, 8139ec7b004SRick Macklem NFSERR_INVAL, 8149ec7b004SRick Macklem NFSERR_ISDIR, 8159ec7b004SRick Macklem NFSERR_LEASEMOVED, 8169ec7b004SRick Macklem NFSERR_MOVED, 8179ec7b004SRick Macklem NFSERR_NAMETOL, 8189ec7b004SRick Macklem NFSERR_NOENT, 8199ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 8209ec7b004SRick Macklem NFSERR_NOGRACE, 8219ec7b004SRick Macklem NFSERR_NOSPC, 8229ec7b004SRick Macklem NFSERR_NOTDIR, 8239ec7b004SRick Macklem NFSERR_NOTSUPP, 8249ec7b004SRick Macklem NFSERR_PERM, 8259ec7b004SRick Macklem NFSERR_RECLAIMBAD, 8269ec7b004SRick Macklem NFSERR_RECLAIMCONFLICT, 8279ec7b004SRick Macklem NFSERR_RESOURCE, 8289ec7b004SRick Macklem NFSERR_ROFS, 8299ec7b004SRick Macklem NFSERR_SERVERFAULT, 8309ec7b004SRick Macklem NFSERR_SHAREDENIED, 8319ec7b004SRick Macklem NFSERR_STALE, 8329ec7b004SRick Macklem NFSERR_STALECLIENTID, 8339ec7b004SRick Macklem NFSERR_SYMLINK, 8349ec7b004SRick Macklem NFSERR_WRONGSEC, 8359ec7b004SRick Macklem 0, 8369ec7b004SRick Macklem }; 8379ec7b004SRick Macklem 8389ec7b004SRick Macklem static short nfsv4err_openattr[] = { 8399ec7b004SRick Macklem NFSERR_IO, 8409ec7b004SRick Macklem NFSERR_ACCES, 8419ec7b004SRick Macklem NFSERR_BADHANDLE, 8429ec7b004SRick Macklem NFSERR_BADXDR, 8439ec7b004SRick Macklem NFSERR_DELAY, 8449ec7b004SRick Macklem NFSERR_DQUOT, 8459ec7b004SRick Macklem NFSERR_FHEXPIRED, 8469ec7b004SRick Macklem NFSERR_IO, 8479ec7b004SRick Macklem NFSERR_MOVED, 8489ec7b004SRick Macklem NFSERR_NOENT, 8499ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 8509ec7b004SRick Macklem NFSERR_NOSPC, 8519ec7b004SRick Macklem NFSERR_NOTSUPP, 8529ec7b004SRick Macklem NFSERR_RESOURCE, 8539ec7b004SRick Macklem NFSERR_ROFS, 8549ec7b004SRick Macklem NFSERR_SERVERFAULT, 8559ec7b004SRick Macklem NFSERR_STALE, 8569ec7b004SRick Macklem 0, 8579ec7b004SRick Macklem }; 8589ec7b004SRick Macklem 8599ec7b004SRick Macklem static short nfsv4err_openconfirm[] = { 8609ec7b004SRick Macklem NFSERR_SERVERFAULT, 8619ec7b004SRick Macklem NFSERR_ADMINREVOKED, 8629ec7b004SRick Macklem NFSERR_BADHANDLE, 8639ec7b004SRick Macklem NFSERR_BADSEQID, 8649ec7b004SRick Macklem NFSERR_BADSTATEID, 8659ec7b004SRick Macklem NFSERR_BADXDR, 8669ec7b004SRick Macklem NFSERR_EXPIRED, 8679ec7b004SRick Macklem NFSERR_FHEXPIRED, 8689ec7b004SRick Macklem NFSERR_INVAL, 8699ec7b004SRick Macklem NFSERR_ISDIR, 8709ec7b004SRick Macklem NFSERR_MOVED, 8719ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 8729ec7b004SRick Macklem NFSERR_OLDSTATEID, 8739ec7b004SRick Macklem NFSERR_RESOURCE, 8749ec7b004SRick Macklem NFSERR_SERVERFAULT, 8759ec7b004SRick Macklem NFSERR_STALE, 8769ec7b004SRick Macklem NFSERR_STALESTATEID, 8779ec7b004SRick Macklem 0, 8789ec7b004SRick Macklem }; 8799ec7b004SRick Macklem 8809ec7b004SRick Macklem static short nfsv4err_opendowngrade[] = { 8819ec7b004SRick Macklem NFSERR_SERVERFAULT, 8829ec7b004SRick Macklem NFSERR_ADMINREVOKED, 8839ec7b004SRick Macklem NFSERR_BADHANDLE, 8849ec7b004SRick Macklem NFSERR_BADSEQID, 8859ec7b004SRick Macklem NFSERR_BADSTATEID, 8869ec7b004SRick Macklem NFSERR_BADXDR, 8879ec7b004SRick Macklem NFSERR_EXPIRED, 8889ec7b004SRick Macklem NFSERR_FHEXPIRED, 8899ec7b004SRick Macklem NFSERR_INVAL, 8909ec7b004SRick Macklem NFSERR_MOVED, 8919ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 8929ec7b004SRick Macklem NFSERR_OLDSTATEID, 8939ec7b004SRick Macklem NFSERR_RESOURCE, 8949ec7b004SRick Macklem NFSERR_SERVERFAULT, 8959ec7b004SRick Macklem NFSERR_STALE, 8969ec7b004SRick Macklem NFSERR_STALESTATEID, 8979ec7b004SRick Macklem 0, 8989ec7b004SRick Macklem }; 8999ec7b004SRick Macklem 9009ec7b004SRick Macklem static short nfsv4err_putfh[] = { 9019ec7b004SRick Macklem NFSERR_SERVERFAULT, 9029ec7b004SRick Macklem NFSERR_BADHANDLE, 9039ec7b004SRick Macklem NFSERR_BADXDR, 9049ec7b004SRick Macklem NFSERR_FHEXPIRED, 9059ec7b004SRick Macklem NFSERR_MOVED, 9069ec7b004SRick Macklem NFSERR_RESOURCE, 9079ec7b004SRick Macklem NFSERR_SERVERFAULT, 9089ec7b004SRick Macklem NFSERR_STALE, 9099ec7b004SRick Macklem NFSERR_WRONGSEC, 9109ec7b004SRick Macklem 0, 9119ec7b004SRick Macklem }; 9129ec7b004SRick Macklem 9139ec7b004SRick Macklem static short nfsv4err_putpubfh[] = { 9149ec7b004SRick Macklem NFSERR_SERVERFAULT, 9159ec7b004SRick Macklem NFSERR_RESOURCE, 9169ec7b004SRick Macklem NFSERR_SERVERFAULT, 9179ec7b004SRick Macklem NFSERR_WRONGSEC, 9189ec7b004SRick Macklem 0, 9199ec7b004SRick Macklem }; 9209ec7b004SRick Macklem 9219ec7b004SRick Macklem static short nfsv4err_putrootfh[] = { 9229ec7b004SRick Macklem NFSERR_SERVERFAULT, 9239ec7b004SRick Macklem NFSERR_RESOURCE, 9249ec7b004SRick Macklem NFSERR_SERVERFAULT, 9259ec7b004SRick Macklem NFSERR_WRONGSEC, 9269ec7b004SRick Macklem 0, 9279ec7b004SRick Macklem }; 9289ec7b004SRick Macklem 9299ec7b004SRick Macklem static short nfsv4err_read[] = { 9309ec7b004SRick Macklem NFSERR_IO, 9319ec7b004SRick Macklem NFSERR_ACCES, 9329ec7b004SRick Macklem NFSERR_ADMINREVOKED, 9339ec7b004SRick Macklem NFSERR_BADHANDLE, 9349ec7b004SRick Macklem NFSERR_BADSTATEID, 9359ec7b004SRick Macklem NFSERR_BADXDR, 9369ec7b004SRick Macklem NFSERR_DELAY, 9379ec7b004SRick Macklem NFSERR_EXPIRED, 9389ec7b004SRick Macklem NFSERR_FHEXPIRED, 9399ec7b004SRick Macklem NFSERR_GRACE, 9409ec7b004SRick Macklem NFSERR_IO, 9419ec7b004SRick Macklem NFSERR_INVAL, 9429ec7b004SRick Macklem NFSERR_ISDIR, 9439ec7b004SRick Macklem NFSERR_LEASEMOVED, 9449ec7b004SRick Macklem NFSERR_LOCKED, 9459ec7b004SRick Macklem NFSERR_MOVED, 9469ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 9479ec7b004SRick Macklem NFSERR_NXIO, 9489ec7b004SRick Macklem NFSERR_OLDSTATEID, 9499ec7b004SRick Macklem NFSERR_OPENMODE, 9509ec7b004SRick Macklem NFSERR_RESOURCE, 9519ec7b004SRick Macklem NFSERR_SERVERFAULT, 9529ec7b004SRick Macklem NFSERR_STALE, 9539ec7b004SRick Macklem NFSERR_STALESTATEID, 9549ec7b004SRick Macklem 0, 9559ec7b004SRick Macklem }; 9569ec7b004SRick Macklem 9579ec7b004SRick Macklem static short nfsv4err_readdir[] = { 9589ec7b004SRick Macklem NFSERR_IO, 9599ec7b004SRick Macklem NFSERR_ACCES, 9609ec7b004SRick Macklem NFSERR_BADHANDLE, 9619ec7b004SRick Macklem NFSERR_BAD_COOKIE, 9629ec7b004SRick Macklem NFSERR_BADXDR, 9639ec7b004SRick Macklem NFSERR_DELAY, 9649ec7b004SRick Macklem NFSERR_FHEXPIRED, 9659ec7b004SRick Macklem NFSERR_INVAL, 9669ec7b004SRick Macklem NFSERR_IO, 9679ec7b004SRick Macklem NFSERR_MOVED, 9689ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 9699ec7b004SRick Macklem NFSERR_NOTDIR, 9709ec7b004SRick Macklem NFSERR_NOTSAME, 9719ec7b004SRick Macklem NFSERR_RESOURCE, 9729ec7b004SRick Macklem NFSERR_SERVERFAULT, 9739ec7b004SRick Macklem NFSERR_STALE, 9749ec7b004SRick Macklem NFSERR_TOOSMALL, 9759ec7b004SRick Macklem 0, 9769ec7b004SRick Macklem }; 9779ec7b004SRick Macklem 9789ec7b004SRick Macklem static short nfsv4err_readlink[] = { 9799ec7b004SRick Macklem NFSERR_IO, 9809ec7b004SRick Macklem NFSERR_ACCES, 9819ec7b004SRick Macklem NFSERR_BADHANDLE, 9829ec7b004SRick Macklem NFSERR_DELAY, 9839ec7b004SRick Macklem NFSERR_FHEXPIRED, 9849ec7b004SRick Macklem NFSERR_INVAL, 9859ec7b004SRick Macklem NFSERR_IO, 9869ec7b004SRick Macklem NFSERR_ISDIR, 9879ec7b004SRick Macklem NFSERR_MOVED, 9889ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 9899ec7b004SRick Macklem NFSERR_NOTSUPP, 9909ec7b004SRick Macklem NFSERR_RESOURCE, 9919ec7b004SRick Macklem NFSERR_SERVERFAULT, 9929ec7b004SRick Macklem NFSERR_STALE, 9939ec7b004SRick Macklem 0, 9949ec7b004SRick Macklem }; 9959ec7b004SRick Macklem 9969ec7b004SRick Macklem static short nfsv4err_remove[] = { 9979ec7b004SRick Macklem NFSERR_IO, 9989ec7b004SRick Macklem NFSERR_ACCES, 9999ec7b004SRick Macklem NFSERR_BADCHAR, 10009ec7b004SRick Macklem NFSERR_BADHANDLE, 10019ec7b004SRick Macklem NFSERR_BADNAME, 10029ec7b004SRick Macklem NFSERR_BADXDR, 10039ec7b004SRick Macklem NFSERR_DELAY, 10049ec7b004SRick Macklem NFSERR_FHEXPIRED, 10059ec7b004SRick Macklem NFSERR_FILEOPEN, 10069ec7b004SRick Macklem NFSERR_INVAL, 10079ec7b004SRick Macklem NFSERR_IO, 10089ec7b004SRick Macklem NFSERR_MOVED, 10099ec7b004SRick Macklem NFSERR_NAMETOL, 10109ec7b004SRick Macklem NFSERR_NOENT, 10119ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 10129ec7b004SRick Macklem NFSERR_NOTDIR, 10139ec7b004SRick Macklem NFSERR_NOTEMPTY, 10149ec7b004SRick Macklem NFSERR_RESOURCE, 10159ec7b004SRick Macklem NFSERR_ROFS, 10169ec7b004SRick Macklem NFSERR_SERVERFAULT, 10179ec7b004SRick Macklem NFSERR_STALE, 10189ec7b004SRick Macklem 0, 10199ec7b004SRick Macklem }; 10209ec7b004SRick Macklem 10219ec7b004SRick Macklem static short nfsv4err_rename[] = { 10229ec7b004SRick Macklem NFSERR_IO, 10239ec7b004SRick Macklem NFSERR_ACCES, 10249ec7b004SRick Macklem NFSERR_BADCHAR, 10259ec7b004SRick Macklem NFSERR_BADHANDLE, 10269ec7b004SRick Macklem NFSERR_BADNAME, 10279ec7b004SRick Macklem NFSERR_BADXDR, 10289ec7b004SRick Macklem NFSERR_DELAY, 10299ec7b004SRick Macklem NFSERR_DQUOT, 10309ec7b004SRick Macklem NFSERR_EXIST, 10319ec7b004SRick Macklem NFSERR_FHEXPIRED, 10329ec7b004SRick Macklem NFSERR_FILEOPEN, 10339ec7b004SRick Macklem NFSERR_INVAL, 10349ec7b004SRick Macklem NFSERR_IO, 10359ec7b004SRick Macklem NFSERR_MOVED, 10369ec7b004SRick Macklem NFSERR_NAMETOL, 10379ec7b004SRick Macklem NFSERR_NOENT, 10389ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 10399ec7b004SRick Macklem NFSERR_NOSPC, 10409ec7b004SRick Macklem NFSERR_NOTDIR, 10419ec7b004SRick Macklem NFSERR_NOTEMPTY, 10429ec7b004SRick Macklem NFSERR_RESOURCE, 10439ec7b004SRick Macklem NFSERR_ROFS, 10449ec7b004SRick Macklem NFSERR_SERVERFAULT, 10459ec7b004SRick Macklem NFSERR_STALE, 10469ec7b004SRick Macklem NFSERR_WRONGSEC, 10479ec7b004SRick Macklem NFSERR_XDEV, 10489ec7b004SRick Macklem 0, 10499ec7b004SRick Macklem }; 10509ec7b004SRick Macklem 10519ec7b004SRick Macklem static short nfsv4err_renew[] = { 10529ec7b004SRick Macklem NFSERR_SERVERFAULT, 10539ec7b004SRick Macklem NFSERR_ACCES, 10549ec7b004SRick Macklem NFSERR_ADMINREVOKED, 10559ec7b004SRick Macklem NFSERR_BADXDR, 10569ec7b004SRick Macklem NFSERR_CBPATHDOWN, 10579ec7b004SRick Macklem NFSERR_EXPIRED, 10589ec7b004SRick Macklem NFSERR_LEASEMOVED, 10599ec7b004SRick Macklem NFSERR_RESOURCE, 10609ec7b004SRick Macklem NFSERR_SERVERFAULT, 10619ec7b004SRick Macklem NFSERR_STALECLIENTID, 10629ec7b004SRick Macklem 0, 10639ec7b004SRick Macklem }; 10649ec7b004SRick Macklem 10659ec7b004SRick Macklem static short nfsv4err_restorefh[] = { 10669ec7b004SRick Macklem NFSERR_SERVERFAULT, 10679ec7b004SRick Macklem NFSERR_BADHANDLE, 10689ec7b004SRick Macklem NFSERR_FHEXPIRED, 10699ec7b004SRick Macklem NFSERR_MOVED, 10709ec7b004SRick Macklem NFSERR_RESOURCE, 10719ec7b004SRick Macklem NFSERR_RESTOREFH, 10729ec7b004SRick Macklem NFSERR_SERVERFAULT, 10739ec7b004SRick Macklem NFSERR_STALE, 10749ec7b004SRick Macklem NFSERR_WRONGSEC, 10759ec7b004SRick Macklem 0, 10769ec7b004SRick Macklem }; 10779ec7b004SRick Macklem 10789ec7b004SRick Macklem static short nfsv4err_savefh[] = { 10799ec7b004SRick Macklem NFSERR_SERVERFAULT, 10809ec7b004SRick Macklem NFSERR_BADHANDLE, 10819ec7b004SRick Macklem NFSERR_FHEXPIRED, 10829ec7b004SRick Macklem NFSERR_MOVED, 10839ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 10849ec7b004SRick Macklem NFSERR_RESOURCE, 10859ec7b004SRick Macklem NFSERR_SERVERFAULT, 10869ec7b004SRick Macklem NFSERR_STALE, 10879ec7b004SRick Macklem 0, 10889ec7b004SRick Macklem }; 10899ec7b004SRick Macklem 10909ec7b004SRick Macklem static short nfsv4err_secinfo[] = { 10919ec7b004SRick Macklem NFSERR_SERVERFAULT, 10929ec7b004SRick Macklem NFSERR_ACCES, 10939ec7b004SRick Macklem NFSERR_BADCHAR, 10949ec7b004SRick Macklem NFSERR_BADHANDLE, 10959ec7b004SRick Macklem NFSERR_BADNAME, 10969ec7b004SRick Macklem NFSERR_BADXDR, 10979ec7b004SRick Macklem NFSERR_FHEXPIRED, 10989ec7b004SRick Macklem NFSERR_INVAL, 10999ec7b004SRick Macklem NFSERR_MOVED, 11009ec7b004SRick Macklem NFSERR_NAMETOL, 11019ec7b004SRick Macklem NFSERR_NOENT, 11029ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 11039ec7b004SRick Macklem NFSERR_NOTDIR, 11049ec7b004SRick Macklem NFSERR_RESOURCE, 11059ec7b004SRick Macklem NFSERR_SERVERFAULT, 11069ec7b004SRick Macklem NFSERR_STALE, 11079ec7b004SRick Macklem 0, 11089ec7b004SRick Macklem }; 11099ec7b004SRick Macklem 11109ec7b004SRick Macklem static short nfsv4err_setattr[] = { 11119ec7b004SRick Macklem NFSERR_IO, 11129ec7b004SRick Macklem NFSERR_ACCES, 11139ec7b004SRick Macklem NFSERR_ADMINREVOKED, 11149ec7b004SRick Macklem NFSERR_ATTRNOTSUPP, 11159ec7b004SRick Macklem NFSERR_BADCHAR, 11169ec7b004SRick Macklem NFSERR_BADHANDLE, 11179ec7b004SRick Macklem NFSERR_BADOWNER, 11189ec7b004SRick Macklem NFSERR_BADSTATEID, 11199ec7b004SRick Macklem NFSERR_BADXDR, 11209ec7b004SRick Macklem NFSERR_DELAY, 11219ec7b004SRick Macklem NFSERR_DQUOT, 11229ec7b004SRick Macklem NFSERR_EXPIRED, 11239ec7b004SRick Macklem NFSERR_FBIG, 11249ec7b004SRick Macklem NFSERR_FHEXPIRED, 11259ec7b004SRick Macklem NFSERR_GRACE, 11269ec7b004SRick Macklem NFSERR_INVAL, 11279ec7b004SRick Macklem NFSERR_IO, 11289ec7b004SRick Macklem NFSERR_ISDIR, 11299ec7b004SRick Macklem NFSERR_LOCKED, 11309ec7b004SRick Macklem NFSERR_MOVED, 11319ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 11329ec7b004SRick Macklem NFSERR_NOSPC, 11339ec7b004SRick Macklem NFSERR_OLDSTATEID, 11349ec7b004SRick Macklem NFSERR_OPENMODE, 11359ec7b004SRick Macklem NFSERR_PERM, 11369ec7b004SRick Macklem NFSERR_RESOURCE, 11379ec7b004SRick Macklem NFSERR_ROFS, 11389ec7b004SRick Macklem NFSERR_SERVERFAULT, 11399ec7b004SRick Macklem NFSERR_STALE, 11409ec7b004SRick Macklem NFSERR_STALESTATEID, 11419ec7b004SRick Macklem 0, 11429ec7b004SRick Macklem }; 11439ec7b004SRick Macklem 11449ec7b004SRick Macklem static short nfsv4err_setclientid[] = { 11459ec7b004SRick Macklem NFSERR_SERVERFAULT, 11469ec7b004SRick Macklem NFSERR_BADXDR, 11479ec7b004SRick Macklem NFSERR_CLIDINUSE, 11489ec7b004SRick Macklem NFSERR_INVAL, 11499ec7b004SRick Macklem NFSERR_RESOURCE, 11509ec7b004SRick Macklem NFSERR_SERVERFAULT, 1151ae03cbd7SRick Macklem NFSERR_WRONGSEC, 11529ec7b004SRick Macklem 0, 11539ec7b004SRick Macklem }; 11549ec7b004SRick Macklem 11559ec7b004SRick Macklem static short nfsv4err_setclientidconfirm[] = { 11569ec7b004SRick Macklem NFSERR_SERVERFAULT, 11579ec7b004SRick Macklem NFSERR_BADXDR, 11589ec7b004SRick Macklem NFSERR_CLIDINUSE, 11599ec7b004SRick Macklem NFSERR_RESOURCE, 11609ec7b004SRick Macklem NFSERR_SERVERFAULT, 11619ec7b004SRick Macklem NFSERR_STALECLIENTID, 11629ec7b004SRick Macklem 0, 11639ec7b004SRick Macklem }; 11649ec7b004SRick Macklem 11659ec7b004SRick Macklem static short nfsv4err_verify[] = { 11669ec7b004SRick Macklem NFSERR_SERVERFAULT, 11679ec7b004SRick Macklem NFSERR_ACCES, 11689ec7b004SRick Macklem NFSERR_ATTRNOTSUPP, 11699ec7b004SRick Macklem NFSERR_BADCHAR, 11709ec7b004SRick Macklem NFSERR_BADHANDLE, 11719ec7b004SRick Macklem NFSERR_BADXDR, 11729ec7b004SRick Macklem NFSERR_DELAY, 11739ec7b004SRick Macklem NFSERR_FHEXPIRED, 11749ec7b004SRick Macklem NFSERR_INVAL, 11759ec7b004SRick Macklem NFSERR_MOVED, 11769ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 11779ec7b004SRick Macklem NFSERR_NOTSAME, 11789ec7b004SRick Macklem NFSERR_RESOURCE, 11799ec7b004SRick Macklem NFSERR_SERVERFAULT, 11809ec7b004SRick Macklem NFSERR_STALE, 11819ec7b004SRick Macklem 0, 11829ec7b004SRick Macklem }; 11839ec7b004SRick Macklem 11849ec7b004SRick Macklem static short nfsv4err_write[] = { 11859ec7b004SRick Macklem NFSERR_IO, 11869ec7b004SRick Macklem NFSERR_ACCES, 11879ec7b004SRick Macklem NFSERR_ADMINREVOKED, 11889ec7b004SRick Macklem NFSERR_BADHANDLE, 11899ec7b004SRick Macklem NFSERR_BADSTATEID, 11909ec7b004SRick Macklem NFSERR_BADXDR, 11919ec7b004SRick Macklem NFSERR_DELAY, 11929ec7b004SRick Macklem NFSERR_DQUOT, 11939ec7b004SRick Macklem NFSERR_EXPIRED, 11949ec7b004SRick Macklem NFSERR_FBIG, 11959ec7b004SRick Macklem NFSERR_FHEXPIRED, 11969ec7b004SRick Macklem NFSERR_GRACE, 11979ec7b004SRick Macklem NFSERR_INVAL, 11989ec7b004SRick Macklem NFSERR_IO, 11999ec7b004SRick Macklem NFSERR_ISDIR, 12009ec7b004SRick Macklem NFSERR_LEASEMOVED, 12019ec7b004SRick Macklem NFSERR_LOCKED, 12029ec7b004SRick Macklem NFSERR_MOVED, 12039ec7b004SRick Macklem NFSERR_NOFILEHANDLE, 12049ec7b004SRick Macklem NFSERR_NOSPC, 12059ec7b004SRick Macklem NFSERR_NXIO, 12069ec7b004SRick Macklem NFSERR_OLDSTATEID, 12079ec7b004SRick Macklem NFSERR_OPENMODE, 12089ec7b004SRick Macklem NFSERR_RESOURCE, 12099ec7b004SRick Macklem NFSERR_ROFS, 12109ec7b004SRick Macklem NFSERR_SERVERFAULT, 12119ec7b004SRick Macklem NFSERR_STALE, 12129ec7b004SRick Macklem NFSERR_STALESTATEID, 12139ec7b004SRick Macklem 0, 12149ec7b004SRick Macklem }; 12159ec7b004SRick Macklem 12169ec7b004SRick Macklem static short nfsv4err_releaselockowner[] = { 12179ec7b004SRick Macklem NFSERR_SERVERFAULT, 12189ec7b004SRick Macklem NFSERR_ADMINREVOKED, 12199ec7b004SRick Macklem NFSERR_BADXDR, 12209ec7b004SRick Macklem NFSERR_EXPIRED, 12219ec7b004SRick Macklem NFSERR_LEASEMOVED, 12229ec7b004SRick Macklem NFSERR_LOCKSHELD, 12239ec7b004SRick Macklem NFSERR_RESOURCE, 12249ec7b004SRick Macklem NFSERR_SERVERFAULT, 12259ec7b004SRick Macklem NFSERR_STALECLIENTID, 12269ec7b004SRick Macklem 0, 12279ec7b004SRick Macklem }; 12289ec7b004SRick Macklem 12299ec7b004SRick Macklem static short *nfsrv_v4errmap[] = { 12309ec7b004SRick Macklem nfsv4err_null, 12319ec7b004SRick Macklem nfsv4err_null, 12329ec7b004SRick Macklem nfsv4err_null, 12339ec7b004SRick Macklem nfsv4err_access, 12349ec7b004SRick Macklem nfsv4err_close, 12359ec7b004SRick Macklem nfsv4err_commit, 12369ec7b004SRick Macklem nfsv4err_create, 12379ec7b004SRick Macklem nfsv4err_delegpurge, 12389ec7b004SRick Macklem nfsv4err_delegreturn, 12399ec7b004SRick Macklem nfsv4err_getattr, 12409ec7b004SRick Macklem nfsv4err_getfh, 12419ec7b004SRick Macklem nfsv4err_link, 12429ec7b004SRick Macklem nfsv4err_lock, 12439ec7b004SRick Macklem nfsv4err_lockt, 12449ec7b004SRick Macklem nfsv4err_locku, 12459ec7b004SRick Macklem nfsv4err_lookup, 12469ec7b004SRick Macklem nfsv4err_lookupp, 12479ec7b004SRick Macklem nfsv4err_nverify, 12489ec7b004SRick Macklem nfsv4err_open, 12499ec7b004SRick Macklem nfsv4err_openattr, 12509ec7b004SRick Macklem nfsv4err_openconfirm, 12519ec7b004SRick Macklem nfsv4err_opendowngrade, 12529ec7b004SRick Macklem nfsv4err_putfh, 12539ec7b004SRick Macklem nfsv4err_putpubfh, 12549ec7b004SRick Macklem nfsv4err_putrootfh, 12559ec7b004SRick Macklem nfsv4err_read, 12569ec7b004SRick Macklem nfsv4err_readdir, 12579ec7b004SRick Macklem nfsv4err_readlink, 12589ec7b004SRick Macklem nfsv4err_remove, 12599ec7b004SRick Macklem nfsv4err_rename, 12609ec7b004SRick Macklem nfsv4err_renew, 12619ec7b004SRick Macklem nfsv4err_restorefh, 12629ec7b004SRick Macklem nfsv4err_savefh, 12639ec7b004SRick Macklem nfsv4err_secinfo, 12649ec7b004SRick Macklem nfsv4err_setattr, 12659ec7b004SRick Macklem nfsv4err_setclientid, 12669ec7b004SRick Macklem nfsv4err_setclientidconfirm, 12679ec7b004SRick Macklem nfsv4err_verify, 12689ec7b004SRick Macklem nfsv4err_write, 12699ec7b004SRick Macklem nfsv4err_releaselockowner, 12709ec7b004SRick Macklem }; 12719ec7b004SRick Macklem 12729ec7b004SRick Macklem /* 127318a48314SRick Macklem * Trim tlen bytes off the end of the mbuf list and then ensure 127418a48314SRick Macklem * the end of the last mbuf is nul filled to a long boundary, 127518a48314SRick Macklem * as indicated by the value of "nul". 127618a48314SRick Macklem * Return the last mbuf in the updated list and free and mbufs 127718a48314SRick Macklem * that follow it in the original list. 127818a48314SRick Macklem * This is somewhat different than the old nfsrv_adj() with 127918a48314SRick Macklem * support for ext_pgs mbufs. It frees the remaining mbufs 128018a48314SRick Macklem * instead of setting them 0 length, since lists of ext_pgs 128118a48314SRick Macklem * mbufs are all expected to be non-empty. 12829ec7b004SRick Macklem */ 128318a48314SRick Macklem struct mbuf * 1284ae070589SRick Macklem nfsrv_adj(struct mbuf *mp, int len, int nul) 12859ec7b004SRick Macklem { 128618a48314SRick Macklem struct mbuf *m, *m2; 128718a48314SRick Macklem vm_page_t pg; 128818a48314SRick Macklem int i, lastlen, pgno, plen, tlen, trim; 128918a48314SRick Macklem uint16_t off; 12909ec7b004SRick Macklem char *cp; 12919ec7b004SRick Macklem 12929ec7b004SRick Macklem /* 129318a48314SRick Macklem * Find the last mbuf after adjustment and 129418a48314SRick Macklem * how much it needs to be adjusted by. 12959ec7b004SRick Macklem */ 129618a48314SRick Macklem tlen = 0; 12979ec7b004SRick Macklem m = mp; 12989ec7b004SRick Macklem for (;;) { 129918a48314SRick Macklem tlen += m->m_len; 130028e8046bSRick Macklem if (m->m_next == NULL) 13019ec7b004SRick Macklem break; 130228e8046bSRick Macklem m = m->m_next; 13039ec7b004SRick Macklem } 130418a48314SRick Macklem /* m is now the last mbuf and tlen the total length. */ 130518a48314SRick Macklem 130618a48314SRick Macklem if (len >= m->m_len) { 130718a48314SRick Macklem /* Need to trim away the last mbuf(s). */ 130818a48314SRick Macklem i = tlen - len; 130918a48314SRick Macklem m = mp; 131018a48314SRick Macklem for (;;) { 131118a48314SRick Macklem if (m->m_len >= i) 13129ec7b004SRick Macklem break; 131318a48314SRick Macklem i -= m->m_len; 131418a48314SRick Macklem m = m->m_next; 13159ec7b004SRick Macklem } 131618a48314SRick Macklem lastlen = i; 131718a48314SRick Macklem } else 131818a48314SRick Macklem lastlen = m->m_len - len; 131918a48314SRick Macklem 132018a48314SRick Macklem /* 132118a48314SRick Macklem * m is now the last mbuf after trimming and its length needs to 132218a48314SRick Macklem * be lastlen. 132318a48314SRick Macklem * Adjust the last mbuf and set cp to point to where nuls must be 132418a48314SRick Macklem * written. 132518a48314SRick Macklem */ 132618a48314SRick Macklem if ((m->m_flags & M_EXTPG) != 0) { 132718a48314SRick Macklem pgno = m->m_epg_npgs - 1; 132818a48314SRick Macklem off = (pgno == 0) ? m->m_epg_1st_off : 0; 132918a48314SRick Macklem plen = m_epg_pagelen(m, pgno, off); 133018a48314SRick Macklem if (m->m_len > lastlen) { 133118a48314SRick Macklem /* Trim this mbuf. */ 133218a48314SRick Macklem trim = m->m_len - lastlen; 133318a48314SRick Macklem while (trim >= plen) { 133418a48314SRick Macklem KASSERT(pgno > 0, 133518a48314SRick Macklem ("nfsrv_adj: freeing page 0")); 133618a48314SRick Macklem /* Free page. */ 133718a48314SRick Macklem pg = PHYS_TO_VM_PAGE(m->m_epg_pa[pgno]); 133818a48314SRick Macklem vm_page_unwire_noq(pg); 133918a48314SRick Macklem vm_page_free(pg); 134018a48314SRick Macklem trim -= plen; 134118a48314SRick Macklem m->m_epg_npgs--; 134218a48314SRick Macklem pgno--; 134318a48314SRick Macklem off = (pgno == 0) ? m->m_epg_1st_off : 0; 134418a48314SRick Macklem plen = m_epg_pagelen(m, pgno, off); 13459ec7b004SRick Macklem } 134618a48314SRick Macklem plen -= trim; 134718a48314SRick Macklem m->m_epg_last_len = plen; 134818a48314SRick Macklem m->m_len = lastlen; 134918a48314SRick Macklem } 135018a48314SRick Macklem cp = (char *)(void *)PHYS_TO_DMAP(m->m_epg_pa[pgno]); 135118a48314SRick Macklem cp += off + plen - nul; 135218a48314SRick Macklem } else { 135318a48314SRick Macklem m->m_len = lastlen; 135418a48314SRick Macklem cp = mtod(m, char *) + m->m_len - nul; 135518a48314SRick Macklem } 135618a48314SRick Macklem 135718a48314SRick Macklem /* Write the nul bytes. */ 135818a48314SRick Macklem for (i = 0; i < nul; i++) 135918a48314SRick Macklem *cp++ = '\0'; 136018a48314SRick Macklem 136118a48314SRick Macklem /* Free up any mbufs past "m". */ 136218a48314SRick Macklem m2 = m->m_next; 136318a48314SRick Macklem m->m_next = NULL; 136418a48314SRick Macklem if (m2 != NULL) 136518a48314SRick Macklem m_freem(m2); 136618a48314SRick Macklem return (m); 13679ec7b004SRick Macklem } 13689ec7b004SRick Macklem 13699ec7b004SRick Macklem /* 13709ec7b004SRick Macklem * Make these functions instead of macros, so that the kernel text size 13719ec7b004SRick Macklem * doesn't get too big... 13729ec7b004SRick Macklem */ 1373b9cc3262SRyan Moeller void 13749ec7b004SRick Macklem nfsrv_wcc(struct nfsrv_descript *nd, int before_ret, 13759ec7b004SRick Macklem struct nfsvattr *before_nvap, int after_ret, struct nfsvattr *after_nvap) 13769ec7b004SRick Macklem { 13779ec7b004SRick Macklem u_int32_t *tl; 13789ec7b004SRick Macklem 13799ec7b004SRick Macklem if (before_ret) { 13809ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 13819ec7b004SRick Macklem *tl = newnfs_false; 13829ec7b004SRick Macklem } else { 13839ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, 7 * NFSX_UNSIGNED); 13849ec7b004SRick Macklem *tl++ = newnfs_true; 13859ec7b004SRick Macklem txdr_hyper(before_nvap->na_size, tl); 13869ec7b004SRick Macklem tl += 2; 13879ec7b004SRick Macklem txdr_nfsv3time(&(before_nvap->na_mtime), tl); 13889ec7b004SRick Macklem tl += 2; 13899ec7b004SRick Macklem txdr_nfsv3time(&(before_nvap->na_ctime), tl); 13909ec7b004SRick Macklem } 13919ec7b004SRick Macklem nfsrv_postopattr(nd, after_ret, after_nvap); 13929ec7b004SRick Macklem } 13939ec7b004SRick Macklem 1394b9cc3262SRyan Moeller void 13959ec7b004SRick Macklem nfsrv_postopattr(struct nfsrv_descript *nd, int after_ret, 13969ec7b004SRick Macklem struct nfsvattr *after_nvap) 13979ec7b004SRick Macklem { 13989ec7b004SRick Macklem u_int32_t *tl; 13999ec7b004SRick Macklem 14009ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 14019ec7b004SRick Macklem if (after_ret) 14029ec7b004SRick Macklem *tl = newnfs_false; 14039ec7b004SRick Macklem else { 14049ec7b004SRick Macklem *tl = newnfs_true; 14059ec7b004SRick Macklem nfsrv_fillattr(nd, after_nvap); 14069ec7b004SRick Macklem } 14079ec7b004SRick Macklem } 14089ec7b004SRick Macklem 14099ec7b004SRick Macklem /* 14109ec7b004SRick Macklem * Fill in file attributes for V2 and 3. For V4, call a separate 14119ec7b004SRick Macklem * routine that sifts through all the attribute bits. 14129ec7b004SRick Macklem */ 1413b9cc3262SRyan Moeller void 14149ec7b004SRick Macklem nfsrv_fillattr(struct nfsrv_descript *nd, struct nfsvattr *nvap) 14159ec7b004SRick Macklem { 14169ec7b004SRick Macklem struct nfs_fattr *fp; 14179ec7b004SRick Macklem int fattr_size; 14189ec7b004SRick Macklem 14199ec7b004SRick Macklem /* 14209ec7b004SRick Macklem * Build space for the attribute structure. 14219ec7b004SRick Macklem */ 14229ec7b004SRick Macklem if (nd->nd_flag & ND_NFSV3) 14239ec7b004SRick Macklem fattr_size = NFSX_V3FATTR; 14249ec7b004SRick Macklem else 14259ec7b004SRick Macklem fattr_size = NFSX_V2FATTR; 14269ec7b004SRick Macklem NFSM_BUILD(fp, struct nfs_fattr *, fattr_size); 14279ec7b004SRick Macklem 14289ec7b004SRick Macklem /* 14299ec7b004SRick Macklem * Now just fill it all in. 14309ec7b004SRick Macklem */ 14319ec7b004SRick Macklem fp->fa_nlink = txdr_unsigned(nvap->na_nlink); 14329ec7b004SRick Macklem fp->fa_uid = txdr_unsigned(nvap->na_uid); 14339ec7b004SRick Macklem fp->fa_gid = txdr_unsigned(nvap->na_gid); 14349ec7b004SRick Macklem if (nd->nd_flag & ND_NFSV3) { 14359ec7b004SRick Macklem fp->fa_type = vtonfsv34_type(nvap->na_type); 14369ec7b004SRick Macklem fp->fa_mode = vtonfsv34_mode(nvap->na_mode); 143732fbc5d8SAlan Somers txdr_hyper(nvap->na_size, (uint32_t*)&fp->fa3_size); 143832fbc5d8SAlan Somers txdr_hyper(nvap->na_bytes, (uint32_t*)&fp->fa3_used); 14399ec7b004SRick Macklem fp->fa3_rdev.specdata1 = txdr_unsigned(NFSMAJOR(nvap->na_rdev)); 14409ec7b004SRick Macklem fp->fa3_rdev.specdata2 = txdr_unsigned(NFSMINOR(nvap->na_rdev)); 14419ec7b004SRick Macklem fp->fa3_fsid.nfsuquad[0] = 0; 14429ec7b004SRick Macklem fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(nvap->na_fsid); 144332fbc5d8SAlan Somers txdr_hyper(nvap->na_fileid, (uint32_t*)&fp->fa3_fileid); 14449ec7b004SRick Macklem txdr_nfsv3time(&nvap->na_atime, &fp->fa3_atime); 14459ec7b004SRick Macklem txdr_nfsv3time(&nvap->na_mtime, &fp->fa3_mtime); 14469ec7b004SRick Macklem txdr_nfsv3time(&nvap->na_ctime, &fp->fa3_ctime); 14479ec7b004SRick Macklem } else { 14489ec7b004SRick Macklem fp->fa_type = vtonfsv2_type(nvap->na_type); 14499ec7b004SRick Macklem fp->fa_mode = vtonfsv2_mode(nvap->na_type, nvap->na_mode); 14509ec7b004SRick Macklem fp->fa2_size = txdr_unsigned(nvap->na_size); 14519ec7b004SRick Macklem fp->fa2_blocksize = txdr_unsigned(nvap->na_blocksize); 14529ec7b004SRick Macklem if (nvap->na_type == VFIFO) 14539ec7b004SRick Macklem fp->fa2_rdev = 0xffffffff; 14549ec7b004SRick Macklem else 14559ec7b004SRick Macklem fp->fa2_rdev = txdr_unsigned(nvap->na_rdev); 14569ec7b004SRick Macklem fp->fa2_blocks = txdr_unsigned(nvap->na_bytes / NFS_FABLKSIZE); 14579ec7b004SRick Macklem fp->fa2_fsid = txdr_unsigned(nvap->na_fsid); 14589ec7b004SRick Macklem fp->fa2_fileid = txdr_unsigned(nvap->na_fileid); 14599ec7b004SRick Macklem txdr_nfsv2time(&nvap->na_atime, &fp->fa2_atime); 14609ec7b004SRick Macklem txdr_nfsv2time(&nvap->na_mtime, &fp->fa2_mtime); 14619ec7b004SRick Macklem txdr_nfsv2time(&nvap->na_ctime, &fp->fa2_ctime); 14629ec7b004SRick Macklem } 14639ec7b004SRick Macklem } 14649ec7b004SRick Macklem 14659ec7b004SRick Macklem /* 14669ec7b004SRick Macklem * This function gets a file handle out of an mbuf list. 14679ec7b004SRick Macklem * It returns 0 for success, EBADRPC otherwise. 14689ec7b004SRick Macklem * If sets the third flagp argument to 1 if the file handle is 14699ec7b004SRick Macklem * the public file handle. 14709ec7b004SRick Macklem * For NFSv4, if the length is incorrect, set nd_repstat == NFSERR_BADHANDLE 14719ec7b004SRick Macklem */ 1472b9cc3262SRyan Moeller int 14739ec7b004SRick Macklem nfsrv_mtofh(struct nfsrv_descript *nd, struct nfsrvfh *fhp) 14749ec7b004SRick Macklem { 14759ec7b004SRick Macklem u_int32_t *tl; 14769ec7b004SRick Macklem int error = 0, len, copylen; 14779ec7b004SRick Macklem 14789ec7b004SRick Macklem if (nd->nd_flag & (ND_NFSV3 | ND_NFSV4)) { 14799ec7b004SRick Macklem NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 14809ec7b004SRick Macklem len = fxdr_unsigned(int, *tl); 14819ec7b004SRick Macklem if (len == 0 && nfs_pubfhset && (nd->nd_flag & ND_NFSV3) && 14829ec7b004SRick Macklem nd->nd_procnum == NFSPROC_LOOKUP) { 14839ec7b004SRick Macklem nd->nd_flag |= ND_PUBLOOKUP; 1484a9285ae5SZack Kirsch goto nfsmout; 14859ec7b004SRick Macklem } 148690d2dfabSRick Macklem copylen = len; 148790d2dfabSRick Macklem 148890d2dfabSRick Macklem /* If len == NFSX_V4PNFSFH the RPC is a pNFS DS one. */ 148990d2dfabSRick Macklem if (len == NFSX_V4PNFSFH && (nd->nd_flag & ND_NFSV41) != 0) { 149090d2dfabSRick Macklem copylen = NFSX_MYFH; 149190d2dfabSRick Macklem len = NFSM_RNDUP(len); 149290d2dfabSRick Macklem nd->nd_flag |= ND_DSSERVER; 149390d2dfabSRick Macklem } else if (len < NFSRV_MINFH || len > NFSRV_MAXFH) { 14949ec7b004SRick Macklem if (nd->nd_flag & ND_NFSV4) { 14959ec7b004SRick Macklem if (len > 0 && len <= NFSX_V4FHMAX) { 14969ec7b004SRick Macklem error = nfsm_advance(nd, NFSM_RNDUP(len), -1); 14979ec7b004SRick Macklem if (error) 1498a9285ae5SZack Kirsch goto nfsmout; 14999ec7b004SRick Macklem nd->nd_repstat = NFSERR_BADHANDLE; 1500a9285ae5SZack Kirsch goto nfsmout; 15019ec7b004SRick Macklem } else { 1502a9285ae5SZack Kirsch error = EBADRPC; 1503a9285ae5SZack Kirsch goto nfsmout; 15049ec7b004SRick Macklem } 15059ec7b004SRick Macklem } else { 1506a9285ae5SZack Kirsch error = EBADRPC; 1507a9285ae5SZack Kirsch goto nfsmout; 15089ec7b004SRick Macklem } 15099ec7b004SRick Macklem } 15109ec7b004SRick Macklem } else { 15119ec7b004SRick Macklem /* 15129ec7b004SRick Macklem * For NFSv2, the file handle is always 32 bytes on the 15139ec7b004SRick Macklem * wire, but this server only cares about the first 15149ec7b004SRick Macklem * NFSRV_MAXFH bytes. 15159ec7b004SRick Macklem */ 15169ec7b004SRick Macklem len = NFSX_V2FH; 15179ec7b004SRick Macklem copylen = NFSRV_MAXFH; 15189ec7b004SRick Macklem } 15199ec7b004SRick Macklem NFSM_DISSECT(tl, u_int32_t *, len); 15209ec7b004SRick Macklem if ((nd->nd_flag & ND_NFSV2) && nfs_pubfhset && 15219ec7b004SRick Macklem nd->nd_procnum == NFSPROC_LOOKUP && 15229ec7b004SRick Macklem !NFSBCMP((caddr_t)tl, nfs_v2pubfh, NFSX_V2FH)) { 15239ec7b004SRick Macklem nd->nd_flag |= ND_PUBLOOKUP; 1524a9285ae5SZack Kirsch goto nfsmout; 15259ec7b004SRick Macklem } 15269ec7b004SRick Macklem NFSBCOPY(tl, (caddr_t)fhp->nfsrvfh_data, copylen); 15279ec7b004SRick Macklem fhp->nfsrvfh_len = copylen; 15289ec7b004SRick Macklem nfsmout: 1529a9285ae5SZack Kirsch NFSEXITCODE2(error, nd); 15309ec7b004SRick Macklem return (error); 15319ec7b004SRick Macklem } 15329ec7b004SRick Macklem 15339ec7b004SRick Macklem /* 15349ec7b004SRick Macklem * Map errnos to NFS error numbers. For Version 3 and 4 also filter out error 15359ec7b004SRick Macklem * numbers not specified for the associated procedure. 15369ec7b004SRick Macklem * NFSPROC_NOOP is a special case, where the high order bits of nd_repstat 15379ec7b004SRick Macklem * should be cleared. NFSPROC_NOOP is used to return errors when a valid 15389ec7b004SRick Macklem * RPC procedure is not involved. 15399ec7b004SRick Macklem * Returns the error number in XDR. 15409ec7b004SRick Macklem */ 1541b9cc3262SRyan Moeller int 15429ec7b004SRick Macklem nfsd_errmap(struct nfsrv_descript *nd) 15439ec7b004SRick Macklem { 15449ec7b004SRick Macklem short *defaulterrp, *errp; 15459ec7b004SRick Macklem 15469ec7b004SRick Macklem if (!nd->nd_repstat) 15479ec7b004SRick Macklem return (0); 1548984c71f9SRick Macklem if ((nd->nd_repstat & NFSERR_AUTHERR) != 0) 1549984c71f9SRick Macklem return (txdr_unsigned(NFSERR_ACCES)); 15509ec7b004SRick Macklem if (nd->nd_flag & (ND_NFSV3 | ND_NFSV4)) { 15519ec7b004SRick Macklem if (nd->nd_procnum == NFSPROC_NOOP) 15529ec7b004SRick Macklem return (txdr_unsigned(nd->nd_repstat & 0xffff)); 15539ec7b004SRick Macklem if (nd->nd_flag & ND_NFSV3) 15549ec7b004SRick Macklem errp = defaulterrp = nfsrv_v3errmap[nd->nd_procnum]; 15559ec7b004SRick Macklem else if (nd->nd_repstat == EBADRPC) 15569ec7b004SRick Macklem return (txdr_unsigned(NFSERR_BADXDR)); 15579ec7b004SRick Macklem else if (nd->nd_repstat == NFSERR_MINORVERMISMATCH || 15589ec7b004SRick Macklem nd->nd_repstat == NFSERR_OPILLEGAL) 15599ec7b004SRick Macklem return (txdr_unsigned(nd->nd_repstat)); 156005a39c2cSRick Macklem else if (nd->nd_repstat == NFSERR_REPLYFROMCACHE) 156105a39c2cSRick Macklem return (txdr_unsigned(NFSERR_IO)); 1562c59e4cc3SRick Macklem else if ((nd->nd_flag & ND_NFSV41) != 0) { 1563c59e4cc3SRick Macklem if (nd->nd_repstat == EOPNOTSUPP) 1564c59e4cc3SRick Macklem nd->nd_repstat = NFSERR_NOTSUPP; 1565c59e4cc3SRick Macklem nd->nd_repstat = nfsrv_isannfserr(nd->nd_repstat); 1566c59e4cc3SRick Macklem return (txdr_unsigned(nd->nd_repstat)); 1567c59e4cc3SRick Macklem } else 15689ec7b004SRick Macklem errp = defaulterrp = nfsrv_v4errmap[nd->nd_procnum]; 15699ec7b004SRick Macklem while (*++errp) 15709ec7b004SRick Macklem if (*errp == nd->nd_repstat) 15719ec7b004SRick Macklem return (txdr_unsigned(nd->nd_repstat)); 15729ec7b004SRick Macklem return (txdr_unsigned(*defaulterrp)); 15739ec7b004SRick Macklem } 1574c59e4cc3SRick Macklem if (nd->nd_repstat <= NFSERR_REMOTE) 15759ec7b004SRick Macklem return (txdr_unsigned(nfsrv_v2errmap[nd->nd_repstat - 1])); 15769ec7b004SRick Macklem return (txdr_unsigned(NFSERR_IO)); 15779ec7b004SRick Macklem } 15789ec7b004SRick Macklem 15799ec7b004SRick Macklem /* 1580c59e4cc3SRick Macklem * Check to see if the error is a valid NFS one. If not, replace it with 1581c59e4cc3SRick Macklem * NFSERR_IO. 1582c59e4cc3SRick Macklem */ 1583c59e4cc3SRick Macklem static u_int32_t 1584c59e4cc3SRick Macklem nfsrv_isannfserr(u_int32_t errval) 1585c59e4cc3SRick Macklem { 1586c59e4cc3SRick Macklem 1587c59e4cc3SRick Macklem if (errval == NFSERR_OK) 1588c59e4cc3SRick Macklem return (errval); 1589c057a378SRick Macklem if (errval >= NFSERR_BADHANDLE && errval <= NFSERR_MAXERRVAL) 1590c59e4cc3SRick Macklem return (errval); 1591c59e4cc3SRick Macklem if (errval > 0 && errval <= NFSERR_REMOTE) 1592c59e4cc3SRick Macklem return (nfsrv_v2errmap[errval - 1]); 1593c59e4cc3SRick Macklem return (NFSERR_IO); 1594c59e4cc3SRick Macklem } 1595c59e4cc3SRick Macklem 1596c59e4cc3SRick Macklem /* 15979ec7b004SRick Macklem * Check to see if setting a uid/gid is permitted when creating a new 15989ec7b004SRick Macklem * file object. (Called when uid and/or gid is specified in the 15999ec7b004SRick Macklem * settable attributes for V4. 16009ec7b004SRick Macklem */ 1601b9cc3262SRyan Moeller int 16029ec7b004SRick Macklem nfsrv_checkuidgid(struct nfsrv_descript *nd, struct nfsvattr *nvap) 16039ec7b004SRick Macklem { 1604a9285ae5SZack Kirsch int error = 0; 16059ec7b004SRick Macklem 16069ec7b004SRick Macklem /* 16079ec7b004SRick Macklem * If not setting either uid nor gid, it's OK. 16089ec7b004SRick Macklem */ 16099ec7b004SRick Macklem if (NFSVNO_NOTSETUID(nvap) && NFSVNO_NOTSETGID(nvap)) 1610a9285ae5SZack Kirsch goto out; 16117e44856eSRick Macklem if ((NFSVNO_ISSETUID(nvap) && 16127e44856eSRick Macklem nvap->na_uid == NFSD_VNET(nfsrv_defaultuid) && 16137e44856eSRick Macklem enable_nobodycheck == 1) || 16147e44856eSRick Macklem (NFSVNO_ISSETGID(nvap) && 16157e44856eSRick Macklem nvap->na_gid == NFSD_VNET(nfsrv_defaultgid) && 16163dd6b7ffSMarcelo Araujo enable_nogroupcheck == 1)) { 1617a9285ae5SZack Kirsch error = NFSERR_BADOWNER; 1618a9285ae5SZack Kirsch goto out; 1619a9285ae5SZack Kirsch } 16209ec7b004SRick Macklem if (nd->nd_cred->cr_uid == 0) 1621a9285ae5SZack Kirsch goto out; 16229ec7b004SRick Macklem if ((NFSVNO_ISSETUID(nvap) && nvap->na_uid != nd->nd_cred->cr_uid) || 1623*caa309c8SRick Macklem (NFSVNO_ISSETGID(nvap) && 16249ec7b004SRick Macklem !groupmember(nvap->na_gid, nd->nd_cred))) 1625a9285ae5SZack Kirsch error = NFSERR_PERM; 1626a9285ae5SZack Kirsch 1627a9285ae5SZack Kirsch out: 1628a9285ae5SZack Kirsch NFSEXITCODE2(error, nd); 1629a9285ae5SZack Kirsch return (error); 16309ec7b004SRick Macklem } 16319ec7b004SRick Macklem 16329ec7b004SRick Macklem /* 16339ec7b004SRick Macklem * and this routine fixes up the settable attributes for V4 if allowed 16349ec7b004SRick Macklem * by nfsrv_checkuidgid(). 16359ec7b004SRick Macklem */ 1636b9cc3262SRyan Moeller void 16379ec7b004SRick Macklem nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp, 16389ec7b004SRick Macklem struct nfsvattr *nvap, NFSACL_T *aclp, NFSPROC_T *p, nfsattrbit_t *attrbitp, 16399ec7b004SRick Macklem struct nfsexstuff *exp) 16409ec7b004SRick Macklem { 16419ec7b004SRick Macklem int change = 0; 16429ec7b004SRick Macklem struct nfsvattr nva; 16439ec7b004SRick Macklem uid_t tuid; 16449ec7b004SRick Macklem int error; 16459ec7b004SRick Macklem nfsattrbit_t nattrbits; 16469ec7b004SRick Macklem 16479ec7b004SRick Macklem /* 16489ec7b004SRick Macklem * Maybe this should be done for V2 and 3 but it never has been 16499ec7b004SRick Macklem * and nobody seems to be upset, so I think it's best not to change 16509ec7b004SRick Macklem * the V2 and 3 semantics. 16519ec7b004SRick Macklem */ 16529ec7b004SRick Macklem if ((nd->nd_flag & ND_NFSV4) == 0) 1653a9285ae5SZack Kirsch goto out; 16549ec7b004SRick Macklem NFSVNO_ATTRINIT(&nva); 16559ec7b004SRick Macklem NFSZERO_ATTRBIT(&nattrbits); 16569ec7b004SRick Macklem tuid = nd->nd_cred->cr_uid; 16579ec7b004SRick Macklem if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_OWNER) && 16589ec7b004SRick Macklem NFSVNO_ISSETUID(nvap) && 16599ec7b004SRick Macklem nvap->na_uid != nd->nd_cred->cr_uid) { 16609ec7b004SRick Macklem if (nd->nd_cred->cr_uid == 0) { 16619ec7b004SRick Macklem nva.na_uid = nvap->na_uid; 16629ec7b004SRick Macklem change++; 16639ec7b004SRick Macklem NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_OWNER); 16649ec7b004SRick Macklem } else { 16659ec7b004SRick Macklem NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_OWNER); 16669ec7b004SRick Macklem } 16679ec7b004SRick Macklem } 16689ec7b004SRick Macklem if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_TIMEACCESSSET) && 16699ec7b004SRick Macklem NFSVNO_ISSETATIME(nvap)) { 16709ec7b004SRick Macklem nva.na_atime = nvap->na_atime; 16719ec7b004SRick Macklem change++; 16729ec7b004SRick Macklem NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_TIMEACCESSSET); 16739ec7b004SRick Macklem } 16749ec7b004SRick Macklem if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_TIMEMODIFYSET) && 16759ec7b004SRick Macklem NFSVNO_ISSETMTIME(nvap)) { 16769ec7b004SRick Macklem nva.na_mtime = nvap->na_mtime; 16779ec7b004SRick Macklem change++; 16789ec7b004SRick Macklem NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_TIMEMODIFYSET); 16799ec7b004SRick Macklem } 16809ec7b004SRick Macklem if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_OWNERGROUP) && 16819ec7b004SRick Macklem NFSVNO_ISSETGID(nvap)) { 1682*caa309c8SRick Macklem if (groupmember(nvap->na_gid, nd->nd_cred)) { 16839ec7b004SRick Macklem nd->nd_cred->cr_uid = 0; 16849ec7b004SRick Macklem nva.na_gid = nvap->na_gid; 16859ec7b004SRick Macklem change++; 16869ec7b004SRick Macklem NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_OWNERGROUP); 16879ec7b004SRick Macklem } else { 16889ec7b004SRick Macklem NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_OWNERGROUP); 16899ec7b004SRick Macklem } 16909ec7b004SRick Macklem } 16919ec7b004SRick Macklem if (change) { 16929ec7b004SRick Macklem error = nfsvno_setattr(vp, &nva, nd->nd_cred, p, exp); 16939ec7b004SRick Macklem if (error) { 16949ec7b004SRick Macklem NFSCLRALL_ATTRBIT(attrbitp, &nattrbits); 16959ec7b004SRick Macklem } 16969ec7b004SRick Macklem } 16979ec7b004SRick Macklem if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SIZE) && 16989ec7b004SRick Macklem NFSVNO_ISSETSIZE(nvap) && nvap->na_size != (u_quad_t)0) { 16999ec7b004SRick Macklem NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_SIZE); 17009ec7b004SRick Macklem } 17019ec7b004SRick Macklem #ifdef NFS4_ACL_EXTATTR_NAME 17029ec7b004SRick Macklem if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ACL) && 17039ec7b004SRick Macklem nfsrv_useacl != 0 && aclp != NULL) { 17049ec7b004SRick Macklem if (aclp->acl_cnt > 0) { 17059ec7b004SRick Macklem error = nfsrv_setacl(vp, aclp, nd->nd_cred, p); 17069ec7b004SRick Macklem if (error) { 17079ec7b004SRick Macklem NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL); 17089ec7b004SRick Macklem } 17099ec7b004SRick Macklem } 17109ec7b004SRick Macklem } else 17119ec7b004SRick Macklem #endif 17129ec7b004SRick Macklem NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL); 17139ec7b004SRick Macklem nd->nd_cred->cr_uid = tuid; 1714a9285ae5SZack Kirsch 1715a9285ae5SZack Kirsch out: 1716a9285ae5SZack Kirsch NFSEXITCODE2(0, nd); 17179ec7b004SRick Macklem } 17189ec7b004SRick Macklem 17199ec7b004SRick Macklem /* 17209ec7b004SRick Macklem * Translate an ASCII hex digit to it's binary value. Return -1 if the 17219ec7b004SRick Macklem * char isn't a hex digit. 17229ec7b004SRick Macklem */ 17239ec7b004SRick Macklem static char 17249ec7b004SRick Macklem nfsrv_hexdigit(char c, int *err) 17259ec7b004SRick Macklem { 17269ec7b004SRick Macklem 17279ec7b004SRick Macklem *err = 0; 17289ec7b004SRick Macklem if (c >= '0' && c <= '9') 17299ec7b004SRick Macklem return (c - '0'); 17309ec7b004SRick Macklem if (c >= 'a' && c <= 'f') 17319ec7b004SRick Macklem return (c - 'a' + ((char)10)); 17329ec7b004SRick Macklem if (c >= 'A' && c <= 'F') 17339ec7b004SRick Macklem return (c - 'A' + ((char)10)); 17349ec7b004SRick Macklem /* Not valid ! */ 17359ec7b004SRick Macklem *err = 1; 17369ec7b004SRick Macklem return (1); /* BOGUS */ 17379ec7b004SRick Macklem } 17389ec7b004SRick Macklem 17399ec7b004SRick Macklem /* 17409ec7b004SRick Macklem * Check to see if NFSERR_MOVED can be returned for this op. Return 1 iff 17419ec7b004SRick Macklem * it can be. 17429ec7b004SRick Macklem */ 1743b9cc3262SRyan Moeller int 17449ec7b004SRick Macklem nfsrv_errmoved(int op) 17459ec7b004SRick Macklem { 17469ec7b004SRick Macklem short *errp; 17479ec7b004SRick Macklem 17489ec7b004SRick Macklem errp = nfsrv_v4errmap[op]; 17499ec7b004SRick Macklem while (*errp != 0) { 17509ec7b004SRick Macklem if (*errp == NFSERR_MOVED) 17519ec7b004SRick Macklem return (1); 17529ec7b004SRick Macklem errp++; 17539ec7b004SRick Macklem } 17549ec7b004SRick Macklem return (0); 17559ec7b004SRick Macklem } 17569ec7b004SRick Macklem 17579ec7b004SRick Macklem /* 17589ec7b004SRick Macklem * Fill in attributes for a Referral. 17599ec7b004SRick Macklem * (Return the number of bytes of XDR created.) 17609ec7b004SRick Macklem */ 1761b9cc3262SRyan Moeller int 17629ec7b004SRick Macklem nfsrv_putreferralattr(struct nfsrv_descript *nd, nfsattrbit_t *retbitp, 17639ec7b004SRick Macklem struct nfsreferral *refp, int getattr, int *reterrp) 17649ec7b004SRick Macklem { 17659ec7b004SRick Macklem u_int32_t *tl, *retnump; 17669ec7b004SRick Macklem u_char *cp, *cp2; 17679ec7b004SRick Macklem int prefixnum, retnum = 0, i, len, bitpos, rderrbit = 0, nonrefbit = 0; 17689ec7b004SRick Macklem int fslocationsbit = 0; 17699ec7b004SRick Macklem nfsattrbit_t tmpbits, refbits; 17709ec7b004SRick Macklem 17719ec7b004SRick Macklem NFSREFERRAL_ATTRBIT(&refbits); 17729ec7b004SRick Macklem if (getattr) 17739ec7b004SRick Macklem NFSCLRBIT_ATTRBIT(&refbits, NFSATTRBIT_RDATTRERROR); 17749ec7b004SRick Macklem else if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_RDATTRERROR)) 17759ec7b004SRick Macklem rderrbit = 1; 17769ec7b004SRick Macklem if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_FSLOCATIONS)) 17779ec7b004SRick Macklem fslocationsbit = 1; 17789ec7b004SRick Macklem 17799ec7b004SRick Macklem /* 17809ec7b004SRick Macklem * Check for the case where unsupported referral attributes are 17819ec7b004SRick Macklem * requested. 17829ec7b004SRick Macklem */ 17839ec7b004SRick Macklem NFSSET_ATTRBIT(&tmpbits, retbitp); 17849ec7b004SRick Macklem NFSCLRALL_ATTRBIT(&tmpbits, &refbits); 17859ec7b004SRick Macklem if (NFSNONZERO_ATTRBIT(&tmpbits)) 17869ec7b004SRick Macklem nonrefbit = 1; 17879ec7b004SRick Macklem 17889ec7b004SRick Macklem if (nonrefbit && !fslocationsbit && (getattr || !rderrbit)) { 17899ec7b004SRick Macklem *reterrp = NFSERR_MOVED; 17909ec7b004SRick Macklem return (0); 17919ec7b004SRick Macklem } 17929ec7b004SRick Macklem 17939ec7b004SRick Macklem /* 17949ec7b004SRick Macklem * Now we can fill in the attributes. 17959ec7b004SRick Macklem */ 17969ec7b004SRick Macklem NFSSET_ATTRBIT(&tmpbits, retbitp); 17979ec7b004SRick Macklem NFSCLRNOT_ATTRBIT(&tmpbits, &refbits); 17989ec7b004SRick Macklem 17999ec7b004SRick Macklem /* 18009ec7b004SRick Macklem * Put out the attribute bitmap for the ones being filled in 18019ec7b004SRick Macklem * and get the field for the number of attributes returned. 18029ec7b004SRick Macklem */ 18039ec7b004SRick Macklem prefixnum = nfsrv_putattrbit(nd, &tmpbits); 18049ec7b004SRick Macklem NFSM_BUILD(retnump, u_int32_t *, NFSX_UNSIGNED); 18059ec7b004SRick Macklem prefixnum += NFSX_UNSIGNED; 18069ec7b004SRick Macklem 18079ec7b004SRick Macklem /* 18089ec7b004SRick Macklem * Now, loop around filling in the attributes for each bit set. 18099ec7b004SRick Macklem */ 18109ec7b004SRick Macklem for (bitpos = 0; bitpos < NFSATTRBIT_MAX; bitpos++) { 18119ec7b004SRick Macklem if (NFSISSET_ATTRBIT(&tmpbits, bitpos)) { 18129ec7b004SRick Macklem switch (bitpos) { 18139ec7b004SRick Macklem case NFSATTRBIT_TYPE: 18149ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 18159ec7b004SRick Macklem *tl = txdr_unsigned(NFDIR); 18169ec7b004SRick Macklem retnum += NFSX_UNSIGNED; 18179ec7b004SRick Macklem break; 18189ec7b004SRick Macklem case NFSATTRBIT_FSID: 18199ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_V4FSID); 18209ec7b004SRick Macklem *tl++ = 0; 18219ec7b004SRick Macklem *tl++ = txdr_unsigned(NFSV4ROOT_FSID0); 18229ec7b004SRick Macklem *tl++ = 0; 18239ec7b004SRick Macklem *tl = txdr_unsigned(NFSV4ROOT_REFERRAL); 18249ec7b004SRick Macklem retnum += NFSX_V4FSID; 18259ec7b004SRick Macklem break; 18269ec7b004SRick Macklem case NFSATTRBIT_RDATTRERROR: 18279ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 18289ec7b004SRick Macklem if (nonrefbit) 18299ec7b004SRick Macklem *tl = txdr_unsigned(NFSERR_MOVED); 18309ec7b004SRick Macklem else 18319ec7b004SRick Macklem *tl = 0; 18329ec7b004SRick Macklem retnum += NFSX_UNSIGNED; 18339ec7b004SRick Macklem break; 18349ec7b004SRick Macklem case NFSATTRBIT_FSLOCATIONS: 18359ec7b004SRick Macklem retnum += nfsm_strtom(nd, "/", 1); 18369ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 18379ec7b004SRick Macklem *tl = txdr_unsigned(refp->nfr_srvcnt); 18389ec7b004SRick Macklem retnum += NFSX_UNSIGNED; 18399ec7b004SRick Macklem cp = refp->nfr_srvlist; 18409ec7b004SRick Macklem for (i = 0; i < refp->nfr_srvcnt; i++) { 18419ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 18429ec7b004SRick Macklem *tl = txdr_unsigned(1); 18439ec7b004SRick Macklem retnum += NFSX_UNSIGNED; 18449ec7b004SRick Macklem cp2 = STRCHR(cp, ':'); 18459ec7b004SRick Macklem if (cp2 != NULL) 18469ec7b004SRick Macklem len = cp2 - cp; 18479ec7b004SRick Macklem else 18489ec7b004SRick Macklem len = 1; 18499ec7b004SRick Macklem retnum += nfsm_strtom(nd, cp, len); 18509ec7b004SRick Macklem if (cp2 != NULL) 18519ec7b004SRick Macklem cp = cp2 + 1; 18529ec7b004SRick Macklem cp2 = STRCHR(cp, ','); 18539ec7b004SRick Macklem if (cp2 != NULL) 18549ec7b004SRick Macklem len = cp2 - cp; 18559ec7b004SRick Macklem else 18569ec7b004SRick Macklem len = strlen(cp); 18579ec7b004SRick Macklem retnum += nfsm_strtom(nd, cp, len); 18589ec7b004SRick Macklem if (cp2 != NULL) 18599ec7b004SRick Macklem cp = cp2 + 1; 18609ec7b004SRick Macklem } 18619ec7b004SRick Macklem break; 18629ec7b004SRick Macklem case NFSATTRBIT_MOUNTEDONFILEID: 18639ec7b004SRick Macklem NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER); 186495ac7f1aSRick Macklem txdr_hyper(refp->nfr_dfileno, tl); 18659ec7b004SRick Macklem retnum += NFSX_HYPER; 18669ec7b004SRick Macklem break; 18679ec7b004SRick Macklem default: 18689ec7b004SRick Macklem printf("EEK! Bad V4 refattr bitpos=%d\n", bitpos); 186974b8d63dSPedro F. Giffuni } 18709ec7b004SRick Macklem } 18719ec7b004SRick Macklem } 18729ec7b004SRick Macklem *retnump = txdr_unsigned(retnum); 18739ec7b004SRick Macklem return (retnum + prefixnum); 18749ec7b004SRick Macklem } 18759ec7b004SRick Macklem 18769ec7b004SRick Macklem /* 18779ec7b004SRick Macklem * Parse a file name out of a request. 18789ec7b004SRick Macklem */ 1879b9cc3262SRyan Moeller int 18809ec7b004SRick Macklem nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp, 18819ec7b004SRick Macklem NFSPATHLEN_T *outlenp) 18829ec7b004SRick Macklem { 18839ec7b004SRick Macklem char *fromcp, *tocp, val = '\0'; 1884ae070589SRick Macklem struct mbuf *md; 18859ec7b004SRick Macklem int i; 18869ec7b004SRick Macklem int rem, len, error = 0, pubtype = 0, outlen = 0, percent = 0; 18879ec7b004SRick Macklem char digit; 18889ec7b004SRick Macklem u_int32_t *tl; 18899ec7b004SRick Macklem u_long hash = 0; 18909ec7b004SRick Macklem 18919ec7b004SRick Macklem if (hashp != NULL) 18929ec7b004SRick Macklem *hashp = 0; 18939ec7b004SRick Macklem tocp = bufp; 18949ec7b004SRick Macklem /* 18959ec7b004SRick Macklem * For V4, check for lookup parent. 18969ec7b004SRick Macklem * Otherwise, get the component name. 18979ec7b004SRick Macklem */ 1898947bd247SRick Macklem if ((nd->nd_flag & ND_NFSV4) && (nd->nd_procnum == NFSV4OP_LOOKUPP || 1899947bd247SRick Macklem nd->nd_procnum == NFSV4OP_SECINFONONAME)) { 19009ec7b004SRick Macklem *tocp++ = '.'; 19019ec7b004SRick Macklem hash += ((u_char)'.'); 19029ec7b004SRick Macklem *tocp++ = '.'; 19039ec7b004SRick Macklem hash += ((u_char)'.'); 19049ec7b004SRick Macklem outlen = 2; 19059ec7b004SRick Macklem } else { 19069ec7b004SRick Macklem /* 19079ec7b004SRick Macklem * First, get the name length. 19089ec7b004SRick Macklem */ 19099ec7b004SRick Macklem NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 19109ec7b004SRick Macklem len = fxdr_unsigned(int, *tl); 19119ec7b004SRick Macklem if (len > NFS_MAXNAMLEN) { 19129ec7b004SRick Macklem nd->nd_repstat = NFSERR_NAMETOL; 1913a9285ae5SZack Kirsch error = 0; 1914a9285ae5SZack Kirsch goto nfsmout; 19159ec7b004SRick Macklem } else if (len <= 0) { 19169ec7b004SRick Macklem nd->nd_repstat = NFSERR_INVAL; 1917a9285ae5SZack Kirsch error = 0; 1918a9285ae5SZack Kirsch goto nfsmout; 19199ec7b004SRick Macklem } 19209ec7b004SRick Macklem 19219ec7b004SRick Macklem /* 19229ec7b004SRick Macklem * Now, copy the component name into the buffer. 19239ec7b004SRick Macklem */ 19249ec7b004SRick Macklem fromcp = nd->nd_dpos; 19259ec7b004SRick Macklem md = nd->nd_md; 192628e8046bSRick Macklem rem = mtod(md, caddr_t) + md->m_len - fromcp; 19279ec7b004SRick Macklem for (i = 0; i < len; i++) { 19289ec7b004SRick Macklem while (rem == 0) { 192928e8046bSRick Macklem md = md->m_next; 1930a9285ae5SZack Kirsch if (md == NULL) { 1931a9285ae5SZack Kirsch error = EBADRPC; 1932a9285ae5SZack Kirsch goto nfsmout; 1933a9285ae5SZack Kirsch } 193428e8046bSRick Macklem fromcp = mtod(md, caddr_t); 193528e8046bSRick Macklem rem = md->m_len; 19369ec7b004SRick Macklem } 19379ec7b004SRick Macklem if (*fromcp == '\0') { 19389ec7b004SRick Macklem nd->nd_repstat = EACCES; 1939a9285ae5SZack Kirsch error = 0; 1940a9285ae5SZack Kirsch goto nfsmout; 19419ec7b004SRick Macklem } 19429ec7b004SRick Macklem /* 19439ec7b004SRick Macklem * For lookups on the public filehandle, do some special 19449ec7b004SRick Macklem * processing on the name. (The public file handle is the 19459ec7b004SRick Macklem * root of the public file system for this server.) 19469ec7b004SRick Macklem */ 19479ec7b004SRick Macklem if (nd->nd_flag & ND_PUBLOOKUP) { 19489ec7b004SRick Macklem /* 19499ec7b004SRick Macklem * If the first char is ASCII, it is a canonical 19509ec7b004SRick Macklem * path, otherwise it is a native path. (RFC2054 19519ec7b004SRick Macklem * doesn't actually state what it is if the first 19529ec7b004SRick Macklem * char isn't ASCII or 0x80, so I assume native.) 19539ec7b004SRick Macklem * pubtype == 1 -> native path 19549ec7b004SRick Macklem * pubtype == 2 -> canonical path 19559ec7b004SRick Macklem */ 19569ec7b004SRick Macklem if (i == 0) { 19579ec7b004SRick Macklem if (*fromcp & 0x80) { 19589ec7b004SRick Macklem /* 19599ec7b004SRick Macklem * Since RFC2054 doesn't indicate 19609ec7b004SRick Macklem * that a native path of just 0x80 19619ec7b004SRick Macklem * isn't allowed, I'll replace the 19629ec7b004SRick Macklem * 0x80 with '/' instead of just 19639ec7b004SRick Macklem * throwing it away. 19649ec7b004SRick Macklem */ 19659ec7b004SRick Macklem *fromcp = '/'; 19669ec7b004SRick Macklem pubtype = 1; 19679ec7b004SRick Macklem } else { 19689ec7b004SRick Macklem pubtype = 2; 19699ec7b004SRick Macklem } 19709ec7b004SRick Macklem } 19719ec7b004SRick Macklem /* 19729ec7b004SRick Macklem * '/' only allowed in a native path 19739ec7b004SRick Macklem */ 19749ec7b004SRick Macklem if (*fromcp == '/' && pubtype != 1) { 19759ec7b004SRick Macklem nd->nd_repstat = EACCES; 1976a9285ae5SZack Kirsch error = 0; 1977a9285ae5SZack Kirsch goto nfsmout; 19789ec7b004SRick Macklem } 19799ec7b004SRick Macklem 19809ec7b004SRick Macklem /* 19819ec7b004SRick Macklem * For the special case of 2 hex digits after a 19829ec7b004SRick Macklem * '%' in an absolute path, calculate the value. 19839ec7b004SRick Macklem * percent == 1 -> indicates "get first hex digit" 19849ec7b004SRick Macklem * percent == 2 -> indicates "get second hex digit" 19859ec7b004SRick Macklem */ 19869ec7b004SRick Macklem if (percent > 0) { 19879ec7b004SRick Macklem digit = nfsrv_hexdigit(*fromcp, &error); 19889ec7b004SRick Macklem if (error) { 19899ec7b004SRick Macklem nd->nd_repstat = EACCES; 1990a9285ae5SZack Kirsch error = 0; 1991a9285ae5SZack Kirsch goto nfsmout; 19929ec7b004SRick Macklem } 19939ec7b004SRick Macklem if (percent == 1) { 19949ec7b004SRick Macklem val = (digit << 4); 19959ec7b004SRick Macklem percent = 2; 19969ec7b004SRick Macklem } else { 19979ec7b004SRick Macklem val += digit; 19989ec7b004SRick Macklem percent = 0; 19999ec7b004SRick Macklem *tocp++ = val; 20009ec7b004SRick Macklem hash += ((u_char)val); 20019ec7b004SRick Macklem outlen++; 20029ec7b004SRick Macklem } 20039ec7b004SRick Macklem } else { 20049ec7b004SRick Macklem if (*fromcp == '%' && pubtype == 2) { 20059ec7b004SRick Macklem /* 20069ec7b004SRick Macklem * Must be followed by 2 hex digits 20079ec7b004SRick Macklem */ 20089ec7b004SRick Macklem if ((len - i) < 3) { 20099ec7b004SRick Macklem nd->nd_repstat = EACCES; 2010a9285ae5SZack Kirsch error = 0; 2011a9285ae5SZack Kirsch goto nfsmout; 20129ec7b004SRick Macklem } 20139ec7b004SRick Macklem percent = 1; 20149ec7b004SRick Macklem } else { 20159ec7b004SRick Macklem *tocp++ = *fromcp; 20169ec7b004SRick Macklem hash += ((u_char)*fromcp); 20179ec7b004SRick Macklem outlen++; 20189ec7b004SRick Macklem } 20199ec7b004SRick Macklem } 20209ec7b004SRick Macklem } else { 20219ec7b004SRick Macklem /* 20229ec7b004SRick Macklem * Normal, non lookup on public, name. 20239ec7b004SRick Macklem */ 20249ec7b004SRick Macklem if (*fromcp == '/') { 20259ec7b004SRick Macklem if (nd->nd_flag & ND_NFSV4) 20269ec7b004SRick Macklem nd->nd_repstat = NFSERR_BADNAME; 20279ec7b004SRick Macklem else 20289ec7b004SRick Macklem nd->nd_repstat = EACCES; 2029a9285ae5SZack Kirsch error = 0; 2030a9285ae5SZack Kirsch goto nfsmout; 20319ec7b004SRick Macklem } 20329ec7b004SRick Macklem hash += ((u_char)*fromcp); 20339ec7b004SRick Macklem *tocp++ = *fromcp; 20349ec7b004SRick Macklem outlen++; 20359ec7b004SRick Macklem } 20369ec7b004SRick Macklem fromcp++; 20379ec7b004SRick Macklem rem--; 20389ec7b004SRick Macklem } 20399ec7b004SRick Macklem nd->nd_md = md; 20409ec7b004SRick Macklem nd->nd_dpos = fromcp; 20419ec7b004SRick Macklem i = NFSM_RNDUP(len) - len; 20429ec7b004SRick Macklem if (i > 0) { 20439ec7b004SRick Macklem if (rem >= i) { 20449ec7b004SRick Macklem nd->nd_dpos += i; 20459ec7b004SRick Macklem } else { 20469ec7b004SRick Macklem error = nfsm_advance(nd, i, rem); 20479ec7b004SRick Macklem if (error) 2048a9285ae5SZack Kirsch goto nfsmout; 20499ec7b004SRick Macklem } 20509ec7b004SRick Macklem } 20519ec7b004SRick Macklem 20529ec7b004SRick Macklem /* 20539ec7b004SRick Macklem * For v4, don't allow lookups of '.' or '..' and 20549ec7b004SRick Macklem * also check for non-utf8 strings. 20559ec7b004SRick Macklem */ 20569ec7b004SRick Macklem if (nd->nd_flag & ND_NFSV4) { 20579ec7b004SRick Macklem if ((outlen == 1 && bufp[0] == '.') || 20589ec7b004SRick Macklem (outlen == 2 && bufp[0] == '.' && 20599ec7b004SRick Macklem bufp[1] == '.')) { 20609ec7b004SRick Macklem nd->nd_repstat = NFSERR_BADNAME; 2061a9285ae5SZack Kirsch error = 0; 2062a9285ae5SZack Kirsch goto nfsmout; 20639ec7b004SRick Macklem } 2064f9246664SMarcelo Araujo if (enable_checkutf8 == 1 && 206534f2e649SRick Macklem nfsrv_checkutf8((u_int8_t *)bufp, outlen)) { 20669ec7b004SRick Macklem nd->nd_repstat = NFSERR_INVAL; 2067a9285ae5SZack Kirsch error = 0; 2068a9285ae5SZack Kirsch goto nfsmout; 20699ec7b004SRick Macklem } 20709ec7b004SRick Macklem } 20719ec7b004SRick Macklem } 20729ec7b004SRick Macklem *tocp = '\0'; 207368c25442SMateusz Guzik *outlenp = (size_t)outlen + 1; 20749ec7b004SRick Macklem if (hashp != NULL) 20759ec7b004SRick Macklem *hashp = hash; 20769ec7b004SRick Macklem nfsmout: 2077a9285ae5SZack Kirsch NFSEXITCODE2(error, nd); 20789ec7b004SRick Macklem return (error); 20799ec7b004SRick Macklem } 20809ec7b004SRick Macklem 20819ec7b004SRick Macklem void 20829ec7b004SRick Macklem nfsd_init(void) 20839ec7b004SRick Macklem { 20849ec7b004SRick Macklem int i; 20859ec7b004SRick Macklem 20869ec7b004SRick Macklem 20879ec7b004SRick Macklem /* 20889ec7b004SRick Macklem * Initialize client queues. Don't free/reinitialize 20899ec7b004SRick Macklem * them when nfsds are restarted. 20909ec7b004SRick Macklem */ 20917e44856eSRick Macklem NFSD_VNET(nfsclienthash) = malloc(sizeof(struct nfsclienthashhead) * 20921f54e596SRick Macklem nfsrv_clienthashsize, M_NFSDCLIENT, M_WAITOK | M_ZERO); 20931f54e596SRick Macklem for (i = 0; i < nfsrv_clienthashsize; i++) 20947e44856eSRick Macklem LIST_INIT(&NFSD_VNET(nfsclienthash)[i]); 20957e44856eSRick Macklem NFSD_VNET(nfslockhash) = malloc(sizeof(struct nfslockhashhead) * 20961f54e596SRick Macklem nfsrv_lockhashsize, M_NFSDLOCKFILE, M_WAITOK | M_ZERO); 20971f54e596SRick Macklem for (i = 0; i < nfsrv_lockhashsize; i++) 20987e44856eSRick Macklem LIST_INIT(&NFSD_VNET(nfslockhash)[i]); 20997e44856eSRick Macklem NFSD_VNET(nfssessionhash) = malloc(sizeof(struct nfssessionhash) * 21001f54e596SRick Macklem nfsrv_sessionhashsize, M_NFSDSESSION, M_WAITOK | M_ZERO); 21011f54e596SRick Macklem for (i = 0; i < nfsrv_sessionhashsize; i++) { 21027e44856eSRick Macklem mtx_init(&NFSD_VNET(nfssessionhash)[i].mtx, "nfssm", NULL, 21037e44856eSRick Macklem MTX_DEF); 21047e44856eSRick Macklem LIST_INIT(&NFSD_VNET(nfssessionhash)[i].list); 21051f54e596SRick Macklem } 210690d2dfabSRick Macklem LIST_INIT(&nfsrv_dontlisthead); 210790d2dfabSRick Macklem TAILQ_INIT(&nfsrv_recalllisthead); 21089ec7b004SRick Macklem 21099ec7b004SRick Macklem /* and the v2 pubfh should be all zeros */ 21109ec7b004SRick Macklem NFSBZERO(nfs_v2pubfh, NFSX_V2FH); 21119ec7b004SRick Macklem } 21129ec7b004SRick Macklem 211398ad4453SRick Macklem /* 211498ad4453SRick Macklem * Check the v4 root exports. 211598ad4453SRick Macklem * Return 0 if ok, 1 otherwise. 211698ad4453SRick Macklem */ 211798ad4453SRick Macklem int 211898ad4453SRick Macklem nfsd_checkrootexp(struct nfsrv_descript *nd) 211998ad4453SRick Macklem { 212098ad4453SRick Macklem 21217e44856eSRick Macklem if (NFSD_VNET(nfs_rootfhset) == 0) 2122984c71f9SRick Macklem return (NFSERR_AUTHERR | AUTH_FAILED); 21235a0050e6SRick Macklem /* 21245a0050e6SRick Macklem * For NFSv4.1/4.2, if the client specifies SP4_NONE, then these 21255a0050e6SRick Macklem * operations are allowed regardless of the value of the "sec=XXX" 21265a0050e6SRick Macklem * field in the V4: exports line. 21275a0050e6SRick Macklem * As such, these Kerberos checks only apply to NFSv4.0 mounts. 21285a0050e6SRick Macklem */ 21295a0050e6SRick Macklem if ((nd->nd_flag & ND_NFSV41) != 0) 21305a0050e6SRick Macklem goto checktls; 213198ad4453SRick Macklem if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS) 21326e4b6ff8SRick Macklem goto checktls; 213398ad4453SRick Macklem if ((nd->nd_flag & (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) == 213498ad4453SRick Macklem (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) 21356e4b6ff8SRick Macklem goto checktls; 213698ad4453SRick Macklem if ((nd->nd_flag & (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) == 213798ad4453SRick Macklem (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) 21386e4b6ff8SRick Macklem goto checktls; 213998ad4453SRick Macklem if ((nd->nd_flag & (ND_GSS | ND_GSSINTEGRITY | ND_GSSPRIVACY | 214098ad4453SRick Macklem ND_EXGSS)) == (ND_GSS | ND_EXGSS)) 21416e4b6ff8SRick Macklem goto checktls; 2142984c71f9SRick Macklem return (NFSERR_AUTHERR | AUTH_TOOWEAK); 21436e4b6ff8SRick Macklem checktls: 21446e4b6ff8SRick Macklem if ((nd->nd_flag & ND_EXTLS) == 0) 21456e4b6ff8SRick Macklem return (0); 21466e4b6ff8SRick Macklem if ((nd->nd_flag & (ND_TLSCERTUSER | ND_EXTLSCERTUSER)) == 21476e4b6ff8SRick Macklem (ND_TLSCERTUSER | ND_EXTLSCERTUSER)) 21486e4b6ff8SRick Macklem return (0); 21496e4b6ff8SRick Macklem if ((nd->nd_flag & (ND_TLSCERT | ND_EXTLSCERT | ND_EXTLSCERTUSER)) == 21506e4b6ff8SRick Macklem (ND_TLSCERT | ND_EXTLSCERT)) 21516e4b6ff8SRick Macklem return (0); 21526e4b6ff8SRick Macklem if ((nd->nd_flag & (ND_TLS | ND_EXTLSCERTUSER | ND_EXTLSCERT)) == 21536e4b6ff8SRick Macklem ND_TLS) 215498ad4453SRick Macklem return (0); 2155744c2dc7SRick Macklem #ifdef notnow 2156744c2dc7SRick Macklem /* There is currently no auth_stat for this. */ 2157984c71f9SRick Macklem if ((nd->nd_flag & ND_TLS) == 0) 2158984c71f9SRick Macklem return (NFSERR_AUTHERR | AUTH_NEEDS_TLS); 2159984c71f9SRick Macklem return (NFSERR_AUTHERR | AUTH_NEEDS_TLS_MUTUAL_HOST); 2160744c2dc7SRick Macklem #endif 2161744c2dc7SRick Macklem return (NFSERR_AUTHERR | AUTH_TOOWEAK); 216298ad4453SRick Macklem } 216398ad4453SRick Macklem 2164c59e4cc3SRick Macklem /* 2165c59e4cc3SRick Macklem * Parse the first part of an NFSv4 compound to find out what the minor 2166c59e4cc3SRick Macklem * version# is. 2167c59e4cc3SRick Macklem */ 2168c59e4cc3SRick Macklem void 2169c59e4cc3SRick Macklem nfsd_getminorvers(struct nfsrv_descript *nd, u_char *tag, u_char **tagstrp, 2170c59e4cc3SRick Macklem int *taglenp, u_int32_t *minversp) 2171c59e4cc3SRick Macklem { 2172c59e4cc3SRick Macklem uint32_t *tl; 2173c59e4cc3SRick Macklem int error = 0, taglen = -1; 2174c59e4cc3SRick Macklem u_char *tagstr = NULL; 2175c59e4cc3SRick Macklem 2176c59e4cc3SRick Macklem NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); 2177c59e4cc3SRick Macklem taglen = fxdr_unsigned(int, *tl); 2178c59e4cc3SRick Macklem if (taglen < 0 || taglen > NFSV4_OPAQUELIMIT) { 2179c59e4cc3SRick Macklem error = EBADRPC; 2180c59e4cc3SRick Macklem goto nfsmout; 2181c59e4cc3SRick Macklem } 2182c59e4cc3SRick Macklem if (taglen <= NFSV4_SMALLSTR) 2183c59e4cc3SRick Macklem tagstr = tag; 2184c59e4cc3SRick Macklem else 2185c59e4cc3SRick Macklem tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK); 2186c59e4cc3SRick Macklem error = nfsrv_mtostr(nd, tagstr, taglen); 2187c59e4cc3SRick Macklem if (error != 0) 2188c59e4cc3SRick Macklem goto nfsmout; 2189c59e4cc3SRick Macklem NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); 2190c59e4cc3SRick Macklem *minversp = fxdr_unsigned(u_int32_t, *tl); 2191c59e4cc3SRick Macklem *tagstrp = tagstr; 2192c59e4cc3SRick Macklem if (*minversp == NFSV41_MINORVERSION) 2193c59e4cc3SRick Macklem nd->nd_flag |= ND_NFSV41; 2194c057a378SRick Macklem else if (*minversp == NFSV42_MINORVERSION) 2195c057a378SRick Macklem nd->nd_flag |= (ND_NFSV41 | ND_NFSV42); 2196c59e4cc3SRick Macklem nfsmout: 2197c59e4cc3SRick Macklem if (error != 0) { 2198c59e4cc3SRick Macklem if (tagstr != NULL && taglen > NFSV4_SMALLSTR) 2199c59e4cc3SRick Macklem free(tagstr, M_TEMP); 2200c59e4cc3SRick Macklem taglen = -1; 2201c59e4cc3SRick Macklem } 2202c59e4cc3SRick Macklem *taglenp = taglen; 2203c59e4cc3SRick Macklem } 2204